LCOV - code coverage report
Current view: top level - oox/source/drawingml - customshapepresetdata.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 497 497 100.0 %
Date: 2014-11-03 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/sequenceasvector.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        7800 : void lcl_parseAdjustmentValue(comphelper::SequenceAsVector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
      26             : {
      27        7800 :     sal_Int32 nIndex = 0;
      28        7800 :     drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue;
      29       23400 :     do
      30             :     {
      31       23400 :         OString aToken = rValue.getToken(0, ',', nIndex).trim();
      32       23400 :         static const OString aNamePrefix("Name = \"");
      33       23400 :         static const OString aValuePrefix("Value = (any) { (long) ");
      34       23400 :         if (aToken.startsWith(aNamePrefix))
      35             :         {
      36        7800 :             OString aName = aToken.copy(aNamePrefix.getLength(), aToken.getLength() - aNamePrefix.getLength() - strlen("\""));
      37        7800 :             aAdjustmentValue.Name = OStringToOUString(aName, RTL_TEXTENCODING_UTF8);
      38             :         }
      39       15600 :         else if (aToken.startsWith(aValuePrefix))
      40             :         {
      41        7800 :             OString aValue = aToken.copy(aValuePrefix.getLength(), aToken.getLength() - aValuePrefix.getLength() - strlen(" }"));
      42        7800 :             aAdjustmentValue.Value = uno::makeAny(aValue.toInt32());
      43             :         }
      44        7800 :         else if (!aToken.startsWith("State = "))
      45       23400 :             SAL_WARN("oox", "lcl_parseAdjustmentValue: unexpected prefix: " << aToken);
      46             :     }
      47       23400 :     while (nIndex >= 0);
      48        7800 :     rAdjustmentValues.push_back(aAdjustmentValue);
      49        7800 : }
      50             : 
      51             : // Parses a string like: { Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj" }, { Value = ..., State = ..., Name = ... }
      52        3198 : void lcl_parseAdjustmentValues(comphelper::SequenceAsVector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
      53             : {
      54        3198 :     sal_Int32 nLevel = 0;
      55        3198 :     sal_Int32 nStart = 0;
      56      838786 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
      57             :     {
      58      835588 :         if (rValue[i] == '{')
      59             :         {
      60       15600 :             if (!nLevel)
      61        7800 :                 nStart = i;
      62       15600 :             nLevel++;
      63             :         }
      64      819988 :         else if (rValue[i] == '}')
      65             :         {
      66       15600 :             nLevel--;
      67       15600 :             if (!nLevel)
      68             :             {
      69        7800 :                 lcl_parseAdjustmentValue(rAdjustmentValues, rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
      70             :             }
      71             :         }
      72             :     }
      73        3198 : }
      74             : 
      75       95784 : drawing::EnhancedCustomShapeParameterPair lcl_parseEnhancedCustomShapeParameterPair(const OString& rValue)
      76             : {
      77       95784 :     drawing::EnhancedCustomShapeParameterPair aPair;
      78      191568 :     OString aToken = rValue;
      79             :     // We expect the followings here: First.Value, First.Type, Second.Value, Second.Type
      80       95784 :     static const OString aExpectedFVPrefix = "First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
      81             :     assert(aToken.startsWith(aExpectedFVPrefix));
      82       95784 :     sal_Int32 nIndex = aExpectedFVPrefix.getLength();
      83       95784 :     aPair.First.Value = uno::makeAny(static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32()));
      84             : 
      85       95784 :     static const OString aExpectedFTPrefix = ", Type = (short) ";
      86       95784 :     aToken = aToken.copy(nIndex);
      87             :     assert(aToken.startsWith(aExpectedFTPrefix));
      88       95784 :     nIndex = aExpectedFTPrefix.getLength();
      89       95784 :     aPair.First.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
      90             : 
      91       95784 :     static const OString aExpectedSVPrefix = ", Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
      92       95784 :     aToken = aToken.copy(nIndex);
      93             :     assert(aToken.startsWith(aExpectedSVPrefix));
      94       95784 :     nIndex = aExpectedSVPrefix.getLength();
      95       95784 :     aPair.Second.Value = uno::makeAny(static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32()));
      96             : 
      97       95784 :     static const OString aExpectedSTPrefix = ", Type = (short) ";
      98       95784 :     aToken = aToken.copy(nIndex);
      99             :     assert(aToken.startsWith(aExpectedSTPrefix));
     100       95784 :     nIndex = aExpectedSTPrefix.getLength();
     101       95784 :     aPair.Second.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
     102      191568 :     return aPair;
     103             : }
     104             : 
     105       56420 : drawing::EnhancedCustomShapeSegment lcl_parseEnhancedCustomShapeSegment(const OString& rValue)
     106             : {
     107       56420 :     drawing::EnhancedCustomShapeSegment aSegment;
     108       56420 :     OString aToken = rValue;
     109             :     // We expect the followings here: Command, Count
     110       56420 :     static const OString aExpectedCommandPrefix = "Command = (short) ";
     111             :     assert(aToken.startsWith(aExpectedCommandPrefix));
     112       56420 :     sal_Int32 nIndex = aExpectedCommandPrefix.getLength();
     113       56420 :     aSegment.Command = static_cast<sal_Int16>(aToken.getToken(0, ',', nIndex).toInt32());
     114             : 
     115       56420 :     static const OString aExpectedCountPrefix = " Count = (short) ";
     116       56420 :     aToken = aToken.copy(nIndex);
     117             :     assert(aToken.startsWith(aExpectedCountPrefix));
     118       56420 :     nIndex = aExpectedCountPrefix.getLength();
     119       56420 :     aSegment.Count = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
     120       56420 :     return aSegment;
     121             : }
     122             : 
     123        4862 : awt::Rectangle lcl_parseRectangle(const OString& rValue)
     124             : {
     125        4862 :     awt::Rectangle aRectangle;
     126        4862 :     OString aToken = rValue;
     127             :     // We expect the followings here: X, Y, Width, Height
     128        4862 :     static const OString aExpectedXPrefix = "X = (long) ";
     129             :     assert(aToken.startsWith(aExpectedXPrefix));
     130        4862 :     sal_Int32 nIndex = aExpectedXPrefix.getLength();
     131        4862 :     aRectangle.X = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
     132             : 
     133        4862 :     static const OString aExpectedYPrefix = " Y = (long) ";
     134        4862 :     aToken = aToken.copy(nIndex);
     135             :     assert(aToken.startsWith(aExpectedYPrefix));
     136        4862 :     nIndex = aExpectedYPrefix.getLength();
     137        4862 :     aRectangle.Y = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
     138             : 
     139        4862 :     static const OString aExpectedWidthPrefix = " Width = (long) ";
     140        4862 :     aToken = aToken.copy(nIndex);
     141             :     assert(aToken.startsWith(aExpectedWidthPrefix));
     142        4862 :     nIndex = aExpectedWidthPrefix.getLength();
     143        4862 :     aRectangle.Width = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
     144             : 
     145        4862 :     static const OString aExpectedHeightPrefix = " Height = (long) ";
     146        4862 :     aToken = aToken.copy(nIndex);
     147             :     assert(aToken.startsWith(aExpectedHeightPrefix));
     148        4862 :     nIndex = aExpectedHeightPrefix.getLength();
     149        4862 :     aRectangle.Width = static_cast<sal_Int32>(aToken.copy(nIndex).toInt32());
     150             : 
     151        4862 :     return aRectangle;
     152             : }
     153             : 
     154        1378 : awt::Size lcl_parseSize(const OString& rValue)
     155             : {
     156        1378 :     awt::Size aSize;
     157        1378 :     OString aToken = rValue;
     158             :     // We expect the followings here: Width, Height
     159        1378 :     static const OString aExpectedWidthPrefix = "Width = (long) ";
     160             :     assert(aToken.startsWith(aExpectedWidthPrefix));
     161        1378 :     sal_Int32 nIndex = aExpectedWidthPrefix.getLength();
     162        1378 :     aSize.Width = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
     163             : 
     164        1378 :     static const OString aExpectedHeightPrefix = " Height = (long) ";
     165        1378 :     aToken = aToken.copy(nIndex);
     166             :     assert(aToken.startsWith(aExpectedHeightPrefix));
     167        1378 :     nIndex = aExpectedHeightPrefix.getLength();
     168        1378 :     aSize.Height = static_cast<sal_Int32>(aToken.copy(nIndex).toInt32());
     169             : 
     170        1378 :     return aSize;
     171             : }
     172             : 
     173        4732 : drawing::EnhancedCustomShapeTextFrame lcl_parseEnhancedCustomShapeTextFrame(const OString& rValue)
     174             : {
     175        4732 :     drawing::EnhancedCustomShapeTextFrame aTextFrame;
     176        4732 :     sal_Int32 nLevel = 0;
     177        4732 :     bool bIgnore = false;
     178        4732 :     sal_Int32 nStart = 0;
     179     2776618 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     180             :     {
     181     2771886 :         if (rValue[i] == '{')
     182             :         {
     183       47320 :             if (!nLevel)
     184        9464 :                 bIgnore = true;
     185       47320 :             nLevel++;
     186             :         }
     187     2724566 :         else if (rValue[i] == '}')
     188             :         {
     189       47320 :             nLevel--;
     190       47320 :             if (!nLevel)
     191        9464 :                 bIgnore = false;
     192             :         }
     193     2677246 :         else if (rValue[i] == ',' && !bIgnore)
     194             :         {
     195        4732 :             OString aToken = rValue.copy(nStart, i - nStart);
     196        4732 :             static const OString aExpectedPrefix("TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ");
     197        4732 :             if (aToken.startsWith(aExpectedPrefix))
     198             :             {
     199        4732 :                 aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     200        4732 :                 aTextFrame.TopLeft = lcl_parseEnhancedCustomShapeParameterPair(aToken);
     201             :             }
     202             :             else
     203             :                 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken);
     204        4732 :             nStart = i + strlen(", ");
     205             :         }
     206             :     }
     207             : 
     208        9464 :     OString aToken = rValue.copy(nStart, rValue.getLength() - nStart);
     209        4732 :     static const OString aExpectedPrefix("BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ");
     210        4732 :     if (aToken.startsWith(aExpectedPrefix))
     211             :     {
     212        4732 :         aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     213        4732 :         aTextFrame.BottomRight = lcl_parseEnhancedCustomShapeParameterPair(aToken);
     214             :     }
     215             :     else
     216             :         SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken);
     217             : 
     218        9464 :     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        6318 : void lcl_parseHandlePosition(comphelper::SequenceAsVector<beans::PropertyValue>& rHandle, const OString& rValue)
     224             : {
     225        6318 :     sal_Int32 nLevel = 0;
     226        6318 :     bool bIgnore = false;
     227        6318 :     sal_Int32 nStart = 0;
     228     2488512 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     229             :     {
     230     2482194 :         if (rValue[i] == '{')
     231             :         {
     232       37908 :             if (!nLevel)
     233        6318 :                 bIgnore = true;
     234       37908 :             nLevel++;
     235             :         }
     236     2444286 :         else if (rValue[i] == '}')
     237             :         {
     238       37908 :             nLevel--;
     239       37908 :             if (!nLevel)
     240        6318 :                 bIgnore = false;
     241             :         }
     242     2406378 :         else if (rValue[i] == ',' && !bIgnore)
     243             :         {
     244       18954 :             OString aToken = rValue.copy(nStart, i - nStart);
     245       18954 :             static const OString aExpectedPrefix("Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ");
     246       18954 :             if (aToken.startsWith(aExpectedPrefix))
     247             :             {
     248        6318 :                 aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
     249             : 
     250        6318 :                 beans::PropertyValue aPropertyValue;
     251        6318 :                 aPropertyValue.Name = "Position";
     252        6318 :                 aPropertyValue.Value = uno::makeAny(lcl_parseEnhancedCustomShapeParameterPair(aToken));
     253        6318 :                 rHandle.push_back(aPropertyValue);
     254             :             }
     255       12636 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     256             :                 SAL_WARN("oox", "lcl_parseHandlePosition: unexpected token: " << aToken);
     257       18954 :             nStart = i + strlen(", ");
     258             :         }
     259             :     }
     260        6318 : }
     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       13988 : void lcl_parseHandleRange(comphelper::SequenceAsVector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
     265             : {
     266       13988 :     sal_Int32 nLevel = 0;
     267       13988 :     bool bIgnore = false;
     268       13988 :     sal_Int32 nStart = 0;
     269     3122106 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     270             :     {
     271     3108118 :         if (rValue[i] == '{')
     272             :         {
     273       41964 :             if (!nLevel)
     274       13988 :                 bIgnore = true;
     275       41964 :             nLevel++;
     276             :         }
     277     3066154 :         else if (rValue[i] == '}')
     278             :         {
     279       41964 :             nLevel--;
     280       41964 :             if (!nLevel)
     281       13988 :                 bIgnore = false;
     282             :         }
     283     3024190 :         else if (rValue[i] == ',' && !bIgnore)
     284             :         {
     285       41964 :             OString aToken = rValue.copy(nStart, i - nStart);
     286       41964 :             static const OString aExpectedPrefix("Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { ");
     287       41964 :             if (aToken.startsWith(aExpectedPrefix))
     288             :             {
     289       13988 :                 drawing::EnhancedCustomShapeParameter aParameter;
     290       13988 :                 aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
     291             :                 // We expect the followings here: Value and Type
     292       13988 :                 static const OString aExpectedVPrefix = "Value = (any) { (long) ";
     293             :                 assert(aToken.startsWith(aExpectedVPrefix));
     294       13988 :                 sal_Int32 nIndex = aExpectedVPrefix.getLength();
     295       13988 :                 aParameter.Value = uno::makeAny(aToken.getToken(0, '}', nIndex).toInt32());
     296             : 
     297       13988 :                 static const OString aExpectedTPrefix = ", Type = (short) ";
     298       13988 :                 aToken = aToken.copy(nIndex);
     299             :                 assert(aToken.startsWith(aExpectedTPrefix));
     300       13988 :                 nIndex = aExpectedTPrefix.getLength();
     301       13988 :                 aParameter.Type = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
     302             : 
     303       27976 :                 beans::PropertyValue aPropertyValue;
     304       13988 :                 aPropertyValue.Name = rName;
     305       13988 :                 aPropertyValue.Value = uno::makeAny(aParameter);
     306       27976 :                 rHandle.push_back(aPropertyValue);
     307             : 
     308             :             }
     309       27976 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     310             :                 SAL_WARN("oox", "lcl_parseHandleRange: unexpected token: " << aToken);
     311       41964 :             nStart = i + strlen(", ");
     312             :         }
     313             :     }
     314       13988 : }
     315             : 
     316             : // Parses a string like: Name = "RefY", Handle = (long) 0, Value = (any) { (long) 0 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
     317        6760 : void lcl_parseHandleRef(comphelper::SequenceAsVector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
     318             : {
     319        6760 :     static const OString aExpectedXPrefix("Name = \"RefX\", Handle = (long) 0, Value = (any) { (long) ");
     320        6760 :     static const OString aExpectedYPrefix("Name = \"RefY\", Handle = (long) 0, Value = (any) { (long) ");
     321        6760 :     if (rValue.startsWith(aExpectedXPrefix) || rValue.startsWith(aExpectedYPrefix))
     322             :     {
     323        6760 :         sal_Int32 nIndex = aExpectedXPrefix.getLength();
     324        6760 :         beans::PropertyValue aPropertyValue;
     325        6760 :         aPropertyValue.Name = rName;
     326             :         // We only expect a Value here
     327        6760 :         aPropertyValue.Value = uno::makeAny(rValue.getToken(0, '}', nIndex).toInt32());
     328        6760 :         rHandle.push_back(aPropertyValue);
     329             :     }
     330             :     else
     331             :         SAL_WARN("oox", "lcl_parseHandleRef: unexpected value: " << rValue);
     332        6760 : }
     333             : 
     334        6318 : uno::Sequence<beans::PropertyValue> lcl_parseHandle(const OString& rValue)
     335             : {
     336        6318 :     comphelper::SequenceAsVector<beans::PropertyValue> aRet;
     337        6318 :     sal_Int32 nLevel = 0;
     338        6318 :     sal_Int32 nStart = 0;
     339     6537310 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     340             :     {
     341     6530992 :         if (rValue[i] == '{')
     342             :         {
     343      113698 :             if (!nLevel)
     344       27066 :                 nStart = i;
     345      113698 :             nLevel++;
     346             :         }
     347     6417294 :         else if (rValue[i] == '}')
     348             :         {
     349      113698 :             nLevel--;
     350      113698 :             if (!nLevel)
     351             :             {
     352       27066 :                 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
     353       27066 :                 if (aToken.startsWith("Name = \"Position\""))
     354        6318 :                     lcl_parseHandlePosition(aRet, aToken);
     355       20748 :                 else if (aToken.startsWith("Name = \"RangeXMaximum\""))
     356        3432 :                     lcl_parseHandleRange(aRet, aToken, "RangeXMaximum");
     357       17316 :                 else if (aToken.startsWith("Name = \"RangeXMinimum\""))
     358        3432 :                     lcl_parseHandleRange(aRet, aToken, "RangeXMinimum");
     359       13884 :                 else if (aToken.startsWith("Name = \"RangeYMaximum\""))
     360        3328 :                     lcl_parseHandleRange(aRet, aToken, "RangeYMaximum");
     361       10556 :                 else if (aToken.startsWith("Name = \"RangeYMinimum\""))
     362        3328 :                     lcl_parseHandleRange(aRet, aToken, "RangeYMinimum");
     363        7228 :                 else if (aToken.startsWith("Name = \"RadiusRangeMaximum\""))
     364         234 :                     lcl_parseHandleRange(aRet, aToken, "RadiusRangeMaximum");
     365        6994 :                 else if (aToken.startsWith("Name = \"RadiusRangeMinimum\""))
     366         234 :                     lcl_parseHandleRange(aRet, aToken, "RadiusRangeMinimum");
     367        6760 :                 else if (aToken.startsWith("Name = \"RefX\""))
     368        3432 :                     lcl_parseHandleRef(aRet, aToken, "RefX");
     369        3328 :                 else if (aToken.startsWith("Name = \"RefY\""))
     370        3328 :                     lcl_parseHandleRef(aRet, aToken, "RefY");
     371             :                 else
     372       27066 :                     SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken);
     373             :             }
     374             :         }
     375             :     }
     376        6318 :     return aRet.getAsConstList();
     377             : }
     378             : 
     379        3120 : void lcl_parseHandles(comphelper::SequenceAsVector< uno::Sequence<beans::PropertyValue> >& rHandles, const OString& rValue)
     380             : {
     381        3120 :     sal_Int32 nLevel = 0;
     382        3120 :     sal_Int32 nStart = 0;
     383     6565780 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     384             :     {
     385     6562660 :         if (rValue[i] == '{')
     386             :         {
     387      120016 :             if (!nLevel)
     388        6318 :                 nStart = i;
     389      120016 :             nLevel++;
     390             :         }
     391     6442644 :         else if (rValue[i] == '}')
     392             :         {
     393      120016 :             nLevel--;
     394      120016 :             if (!nLevel)
     395             :             {
     396        6318 :                 uno::Sequence<beans::PropertyValue> aHandle = lcl_parseHandle(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
     397        6318 :                 rHandles.push_back(aHandle);
     398             :             }
     399             :         }
     400             :     }
     401        3120 : }
     402             : 
     403        4784 : void lcl_parseEquations(comphelper::SequenceAsVector<OUString>& rEquations, const OString& rValue)
     404             : {
     405        4784 :     bool bInString = false;
     406        4784 :     sal_Int32 nStart = 0;
     407     2643264 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     408             :     {
     409     2638480 :         if (rValue[i] == '"' && !bInString)
     410             :         {
     411      136500 :             nStart = i;
     412      136500 :             bInString = true;
     413             :         }
     414     2501980 :         else if (rValue[i] == '"' && bInString)
     415             :         {
     416      136500 :             bInString = false;
     417      136500 :             rEquations.push_back(OStringToOUString(rValue.copy(nStart + strlen("\""), i - nStart - strlen("\"")), RTL_TEXTENCODING_UTF8));
     418             :         }
     419             :     }
     420        4784 : }
     421             : 
     422        4862 : void lcl_parsePathCoordinateValues(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     423             : {
     424        4862 :     comphelper::SequenceAsVector<drawing::EnhancedCustomShapeParameterPair> aPairs;
     425        4862 :     sal_Int32 nLevel = 0;
     426        4862 :     sal_Int32 nStart = 0;
     427    18117372 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     428             :     {
     429    18112510 :         if (rValue[i] == '{')
     430             :         {
     431      400010 :             if (!nLevel)
     432       80002 :                 nStart = i;
     433      400010 :             nLevel++;
     434             :         }
     435    17712500 :         else if (rValue[i] == '}')
     436             :         {
     437      400010 :             nLevel--;
     438      400010 :             if (!nLevel)
     439       80002 :                 aPairs.push_back(lcl_parseEnhancedCustomShapeParameterPair(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
     440             :         }
     441             :     }
     442             : 
     443        9724 :     beans::PropertyValue aPropertyValue;
     444        4862 :     aPropertyValue.Name = "Coordinates";
     445        4862 :     aPropertyValue.Value = uno::makeAny(aPairs.getAsConstList());
     446        9724 :     rPath.push_back(aPropertyValue);
     447        4862 : }
     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        4862 : void lcl_parsePathCoordinates(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     452             : {
     453        4862 :     sal_Int32 nLevel = 0;
     454        4862 :     bool bIgnore = false;
     455        4862 :     sal_Int32 nStart = 0;
     456    18982808 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     457             :     {
     458    18977946 :         if (rValue[i] == '{')
     459             :         {
     460      409734 :             if (!nLevel)
     461        4862 :                 bIgnore = true;
     462      409734 :             nLevel++;
     463             :         }
     464    18568212 :         else if (rValue[i] == '}')
     465             :         {
     466      409734 :             nLevel--;
     467      409734 :             if (!nLevel)
     468        4862 :                 bIgnore = false;
     469             :         }
     470    18158478 :         else if (rValue[i] == ',' && !bIgnore)
     471             :         {
     472       14586 :             OString aToken = rValue.copy(nStart, i - nStart);
     473       14586 :             static const OString aExpectedPrefix("Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ");
     474       14586 :             if (aToken.startsWith(aExpectedPrefix))
     475             :             {
     476        4862 :                 aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
     477        4862 :                 lcl_parsePathCoordinateValues(rPath, aToken);
     478             :             }
     479        9724 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     480             :                 SAL_WARN("oox", "lcl_parsePathCoordinates: unexpected token: " << aToken);
     481       14586 :             nStart = i + strlen(", ");
     482             :         }
     483             :     }
     484        4862 : }
     485             : 
     486        4862 : void lcl_parsePathSegmentValues(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     487             : {
     488        4862 :     comphelper::SequenceAsVector<drawing::EnhancedCustomShapeSegment> aSegments;
     489        4862 :     sal_Int32 nLevel = 0;
     490        4862 :     sal_Int32 nStart = 0;
     491     2488096 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     492             :     {
     493     2483234 :         if (rValue[i] == '{')
     494             :         {
     495       56420 :             if (!nLevel)
     496       56420 :                 nStart = i;
     497       56420 :             nLevel++;
     498             :         }
     499     2426814 :         else if (rValue[i] == '}')
     500             :         {
     501       56420 :             nLevel--;
     502       56420 :             if (!nLevel)
     503       56420 :                 aSegments.push_back(lcl_parseEnhancedCustomShapeSegment(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
     504             :         }
     505             :     }
     506             : 
     507        9724 :     beans::PropertyValue aPropertyValue;
     508        4862 :     aPropertyValue.Name = "Segments";
     509        4862 :     aPropertyValue.Value = uno::makeAny(aSegments.getAsConstList());
     510        9724 :     rPath.push_back(aPropertyValue);
     511        4862 : }
     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        4862 : void lcl_parsePathSegments(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     516             : {
     517        4862 :     sal_Int32 nLevel = 0;
     518        4862 :     bool bIgnore = false;
     519        4862 :     sal_Int32 nStart = 0;
     520     3309774 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     521             :     {
     522     3304912 :         if (rValue[i] == '{')
     523             :         {
     524       66144 :             if (!nLevel)
     525        4862 :                 bIgnore = true;
     526       66144 :             nLevel++;
     527             :         }
     528     3238768 :         else if (rValue[i] == '}')
     529             :         {
     530       66144 :             nLevel--;
     531       66144 :             if (!nLevel)
     532        4862 :                 bIgnore = false;
     533             :         }
     534     3172624 :         else if (rValue[i] == ',' && !bIgnore)
     535             :         {
     536       14586 :             OString aToken = rValue.copy(nStart, i - nStart);
     537       14586 :             static const OString aExpectedPrefix("Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { ");
     538       14586 :             if (aToken.startsWith(aExpectedPrefix))
     539             :             {
     540        4862 :                 aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
     541        4862 :                 lcl_parsePathSegmentValues(rPath, aToken);
     542             :             }
     543        9724 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     544             :                 SAL_WARN("oox", "lcl_parsePathSegments: unexpected token: " << aToken);
     545       14586 :             nStart = i + strlen(", ");
     546             :         }
     547             :     }
     548        4862 : }
     549             : 
     550        4732 : void lcl_parsePathTextFrameValues(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     551             : {
     552        4732 :     comphelper::SequenceAsVector<drawing::EnhancedCustomShapeTextFrame> aTextFrames;
     553        4732 :     sal_Int32 nLevel = 0;
     554        4732 :     sal_Int32 nStart = 0;
     555     2795546 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     556             :     {
     557     2790814 :         if (rValue[i] == '{')
     558             :         {
     559       52052 :             if (!nLevel)
     560        4732 :                 nStart = i;
     561       52052 :             nLevel++;
     562             :         }
     563     2738762 :         else if (rValue[i] == '}')
     564             :         {
     565       52052 :             nLevel--;
     566       52052 :             if (!nLevel)
     567        4732 :                 aTextFrames.push_back(lcl_parseEnhancedCustomShapeTextFrame(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
     568             :         }
     569             :     }
     570             : 
     571        9464 :     beans::PropertyValue aPropertyValue;
     572        4732 :     aPropertyValue.Name = "TextFrames";
     573        4732 :     aPropertyValue.Value = uno::makeAny(aTextFrames.getAsConstList());
     574        9464 :     rPath.push_back(aPropertyValue);
     575        4732 : }
     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        4732 : void lcl_parsePathTextFrames(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     580             : {
     581        4732 :     sal_Int32 nLevel = 0;
     582        4732 :     bool bIgnore = false;
     583        4732 :     sal_Int32 nStart = 0;
     584     3614182 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     585             :     {
     586     3609450 :         if (rValue[i] == '{')
     587             :         {
     588       61516 :             if (!nLevel)
     589        4732 :                 bIgnore = true;
     590       61516 :             nLevel++;
     591             :         }
     592     3547934 :         else if (rValue[i] == '}')
     593             :         {
     594       61516 :             nLevel--;
     595       61516 :             if (!nLevel)
     596        4732 :                 bIgnore = false;
     597             :         }
     598     3486418 :         else if (rValue[i] == ',' && !bIgnore)
     599             :         {
     600       14196 :             OString aToken = rValue.copy(nStart, i - nStart);
     601       14196 :             static const OString aExpectedPrefix("Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { ");
     602       14196 :             if (aToken.startsWith(aExpectedPrefix))
     603             :             {
     604        4732 :                 aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
     605        4732 :                 lcl_parsePathTextFrameValues(rPath, aToken);
     606             :             }
     607        9464 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     608             :                 SAL_WARN("oox", "lcl_parsePathTextFrames: unexpected token: " << aToken);
     609       14196 :             nStart = i + strlen(", ");
     610             :         }
     611             :     }
     612        4732 : }
     613             : 
     614         806 : void lcl_parsePathSubViewSizeValues(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     615             : {
     616         806 :     comphelper::SequenceAsVector<awt::Size> aSizes;
     617         806 :     sal_Int32 nLevel = 0;
     618         806 :     sal_Int32 nStart = 0;
     619       58656 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     620             :     {
     621       57850 :         if (rValue[i] == '{')
     622             :         {
     623        1378 :             if (!nLevel)
     624        1378 :                 nStart = i;
     625        1378 :             nLevel++;
     626             :         }
     627       56472 :         else if (rValue[i] == '}')
     628             :         {
     629        1378 :             nLevel--;
     630        1378 :             if (!nLevel)
     631        1378 :                 aSizes.push_back(lcl_parseSize(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
     632             :         }
     633             :     }
     634             : 
     635        1612 :     beans::PropertyValue aPropertyValue;
     636         806 :     aPropertyValue.Name = "SubViewSize";
     637         806 :     aPropertyValue.Value = uno::makeAny(aSizes.getAsConstList());
     638        1612 :     rPath.push_back(aPropertyValue);
     639         806 : }
     640             : 
     641         806 : void lcl_parsePathSubViewSize(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     642             : {
     643         806 :     sal_Int32 nLevel = 0;
     644         806 :     bool bIgnore = false;
     645         806 :     sal_Int32 nStart = 0;
     646      176332 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     647             :     {
     648      175526 :         if (rValue[i] == '{')
     649             :         {
     650        2990 :             if (!nLevel)
     651         806 :                 bIgnore = true;
     652        2990 :             nLevel++;
     653             :         }
     654      172536 :         else if (rValue[i] == '}')
     655             :         {
     656        2990 :             nLevel--;
     657        2990 :             if (!nLevel)
     658         806 :                 bIgnore = false;
     659             :         }
     660      169546 :         else if (rValue[i] == ',' && !bIgnore)
     661             :         {
     662        2418 :             OString aToken = rValue.copy(nStart, i - nStart);
     663        2418 :             static const OString aExpectedPrefix("Value = (any) { ([]com.sun.star.awt.Size) { ");
     664        2418 :             if (aToken.startsWith(aExpectedPrefix))
     665             :             {
     666         806 :                 aToken = aToken.copy(aExpectedPrefix.getLength(), aToken.getLength() - aExpectedPrefix.getLength() - strlen(" } }"));
     667         806 :                 lcl_parsePathSubViewSizeValues(rPath, aToken);
     668             :             }
     669        1612 :             else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
     670             :                 SAL_WARN("oox", "lcl_parsePathSubViewSize: unexpected token: " << aToken);
     671        2418 :             nStart = i + strlen(", ");
     672             :         }
     673             :     }
     674         806 : }
     675             : 
     676        4862 : void lcl_parsePath(comphelper::SequenceAsVector<beans::PropertyValue>& rPath, const OString& rValue)
     677             : {
     678        4862 :     sal_Int32 nLevel = 0;
     679        4862 :     sal_Int32 nStart = 0;
     680    26154544 :     for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
     681             :     {
     682    26149682 :         if (rValue[i] == '{')
     683             :         {
     684      555646 :             if (!nLevel)
     685       15262 :                 nStart = i;
     686      555646 :             nLevel++;
     687             :         }
     688    25594036 :         else if (rValue[i] == '}')
     689             :         {
     690      555646 :             nLevel--;
     691      555646 :             if (!nLevel)
     692             :             {
     693       15262 :                 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
     694       15262 :                 if (aToken.startsWith("Name = \"Coordinates\""))
     695        4862 :                     lcl_parsePathCoordinates(rPath, aToken);
     696       10400 :                 else if (aToken.startsWith("Name = \"Segments\""))
     697        4862 :                     lcl_parsePathSegments(rPath, aToken);
     698        5538 :                 else if (aToken.startsWith("Name = \"TextFrames\""))
     699        4732 :                     lcl_parsePathTextFrames(rPath, aToken);
     700         806 :                 else if (aToken.startsWith("Name = \"SubViewSize\""))
     701         806 :                     lcl_parsePathSubViewSize(rPath, aToken);
     702             :                 else
     703       15262 :                     SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken);
     704             :             }
     705             :         }
     706             :     }
     707        4862 : }
     708             : 
     709             : }
     710             : 
     711             : namespace oox
     712             : {
     713             : namespace drawingml
     714             : {
     715             : 
     716          26 : void CustomShapeProperties::initializePresetDataMap()
     717             : {
     718          26 :     OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/oox-drawingml-cs-presets");
     719          26 :     rtl::Bootstrap::expandMacros(aPath);
     720          52 :     SvFileStream aStream(aPath, STREAM_READ);
     721          26 :     if (aStream.GetError() != ERRCODE_NONE)
     722             :         SAL_WARN("oox", "failed to open oox-drawingml-cs-presets");
     723          52 :     OString aLine;
     724          52 :     OUString aName;
     725          26 :     bool bNotDone = aStream.ReadLine(aLine);
     726          52 :     PropertyMap aPropertyMap;
     727          26 :     bool bFirst = true;
     728       43810 :     while (bNotDone)
     729             :     {
     730       43758 :         static const OString aCommentPrefix("/* ");
     731       43758 :         if (aLine.startsWith(aCommentPrefix))
     732             :         {
     733        4862 :             if (bFirst)
     734          26 :                 bFirst = false;
     735             :             else
     736        4836 :                 maPresetDataMap[StaticTokenMap::get().getTokenFromUnicode(aName)] = aPropertyMap;
     737        4862 :             aName = OStringToOUString(aLine.copy(aCommentPrefix.getLength(), aLine.getLength() - aCommentPrefix.getLength() - strlen(" */")), RTL_TEXTENCODING_UTF8);
     738             :         }
     739             :         else
     740             :         {
     741       38896 :             if (aLine == "AdjustmentValues")
     742             :             {
     743        4862 :                 aStream.ReadLine(aLine);
     744        4862 :                 if (aLine != "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}")
     745             :                 {
     746        3198 :                     comphelper::SequenceAsVector<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustmentValues;
     747        6396 :                     OString aExpectedPrefix("([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { ");
     748             :                     assert(aLine.startsWith(aExpectedPrefix));
     749             : 
     750        6396 :                     OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     751        3198 :                     lcl_parseAdjustmentValues(aAdjustmentValues, aValue);
     752        6396 :                     aPropertyMap.setProperty(PROP_AdjustmentValues, aAdjustmentValues.getAsConstList());
     753             :                 }
     754             :                 else
     755        1664 :                     aPropertyMap.setProperty(PROP_AdjustmentValues, uno::Sequence<OUString>(0));
     756             :             }
     757       34034 :             else if (aLine == "Equations")
     758             :             {
     759        4862 :                 aStream.ReadLine(aLine);
     760        4862 :                 if (aLine != "([]string) {}")
     761             :                 {
     762        4784 :                     comphelper::SequenceAsVector<OUString> aEquations;
     763        9568 :                     OString aExpectedPrefix("([]string) { ");
     764             :                     assert(aLine.startsWith(aExpectedPrefix));
     765             : 
     766        9568 :                     OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     767        4784 :                     lcl_parseEquations(aEquations, aValue);
     768        9568 :                     aPropertyMap.setProperty(PROP_Equations, aEquations.getAsConstList());
     769             :                 }
     770             :                 else
     771          78 :                     aPropertyMap.setProperty(PROP_Equations, uno::Sequence<OUString>(0));
     772             :             }
     773       29172 :             else if (aLine == "Handles")
     774             :             {
     775        4862 :                 aStream.ReadLine(aLine);
     776        4862 :                 if (aLine != "([][]com.sun.star.beans.PropertyValue) {}")
     777             :                 {
     778        3120 :                     comphelper::SequenceAsVector< uno::Sequence<beans::PropertyValue> > aHandles;
     779        6240 :                     OString aExpectedPrefix("([][]com.sun.star.beans.PropertyValue) { ");
     780             :                     assert(aLine.startsWith(aExpectedPrefix));
     781             : 
     782        6240 :                     OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     783        3120 :                     lcl_parseHandles(aHandles, aValue);
     784        6240 :                     aPropertyMap.setProperty(PROP_Handles, aHandles.getAsConstList());
     785             :                 }
     786             :                 else
     787        1742 :                     aPropertyMap.setProperty(PROP_Handles, uno::Sequence<OUString>(0));
     788             :             }
     789       24310 :             else if (aLine == "MirroredX")
     790             :             {
     791        4862 :                 aStream.ReadLine(aLine);
     792        4862 :                 if (aLine == "true" || aLine == "false")
     793             :                 {
     794        4862 :                     aPropertyMap.setProperty(PROP_MirroredX, aLine == "true");
     795             :                 }
     796             :                 else
     797             :                     SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredX parameter");
     798             :             }
     799       19448 :             else if (aLine == "MirroredY")
     800             :             {
     801        4862 :                 aStream.ReadLine(aLine);
     802        4862 :                 if (aLine == "true" || aLine == "false")
     803             :                 {
     804        4862 :                     aPropertyMap.setProperty(PROP_MirroredY, aLine == "true");
     805             :                 }
     806             :                 else
     807             :                     SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredY parameter");
     808             :             }
     809       14586 :             else if (aLine == "Path")
     810             :             {
     811        4862 :                 aStream.ReadLine(aLine);
     812        4862 :                 OString aExpectedPrefix("([]com.sun.star.beans.PropertyValue) { ");
     813             :                 assert(aLine.startsWith(aExpectedPrefix));
     814             : 
     815        9724 :                 comphelper::SequenceAsVector<beans::PropertyValue> aPathValue;
     816        9724 :                 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     817        4862 :                 lcl_parsePath(aPathValue, aValue);
     818        9724 :                 aPropertyMap.setProperty(PROP_Path, aPathValue.getAsConstList());
     819             :             }
     820        9724 :             else if (aLine == "Type")
     821             :             {
     822             :                 // Just ignore the line here, we already know the correct type.
     823        4862 :                 aStream.ReadLine(aLine);
     824        4862 :                 aPropertyMap.setProperty(PROP_Type, "ooxml-" + aName);
     825             :             }
     826        4862 :             else if (aLine == "ViewBox")
     827             :             {
     828        4862 :                 aStream.ReadLine(aLine);
     829        4862 :                 OString aExpectedPrefix("(com.sun.star.awt.Rectangle) { ");
     830             :                 assert(aLine.startsWith(aExpectedPrefix));
     831             : 
     832        9724 :                 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
     833        9724 :                 aPropertyMap.setProperty(PROP_ViewBox, lcl_parseRectangle(aValue));
     834             :             }
     835             :             else
     836             :                 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unhandled line: " << aLine);
     837             :         }
     838       43758 :         bNotDone = aStream.ReadLine(aLine);
     839             :     }
     840          52 :     maPresetDataMap[StaticTokenMap::get().getTokenFromUnicode(aName)] = aPropertyMap;
     841          26 : }
     842             : 
     843             : }
     844         408 : }
     845             : 
     846             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10