fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / oox / source / drawingml / customshapepresetdata.cxx
blob92252f30fa4d79a085754036918b56443e2a8126
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <config_folders.h>
11 #include <rtl/bootstrap.hxx>
12 #include <tools/stream.hxx>
13 #include <comphelper/sequence.hxx>
15 #include "drawingml/customshapeproperties.hxx"
16 #include "oox/token/tokenmap.hxx"
17 #include <com/sun/star/awt/Rectangle.hpp>
19 using namespace ::com::sun::star;
21 namespace
24 // Parses a string like: Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj"
25 void lcl_parseAdjustmentValue(std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
27 sal_Int32 nIndex = 0;
28 drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue;
31 OString aToken = rValue.getToken(0, ',', nIndex).trim();
32 static const char aNamePrefix[] = "Name = \"";
33 static const char aValuePrefix[] = "Value = (any) { (long) ";
34 if (aToken.startsWith(aNamePrefix))
36 OString aName = aToken.copy(strlen(aNamePrefix), aToken.getLength() - strlen(aNamePrefix) - strlen("\""));
37 aAdjustmentValue.Name = OUString::fromUtf8(aName);
39 else if (aToken.startsWith(aValuePrefix))
41 OString aValue = aToken.copy(strlen(aValuePrefix), aToken.getLength() - strlen(aValuePrefix) - strlen(" }"));
42 aAdjustmentValue.Value = uno::makeAny(aValue.toInt32());
44 else if (!aToken.startsWith("State = "))
45 SAL_WARN("oox", "lcl_parseAdjustmentValue: unexpected prefix: " << aToken);
47 while (nIndex >= 0);
48 rAdjustmentValues.push_back(aAdjustmentValue);
51 // Parses a string like: { Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj" }, { Value = ..., State = ..., Name = ... }
52 void lcl_parseAdjustmentValues(std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues, const OString& rValue)
54 sal_Int32 nLevel = 0;
55 sal_Int32 nStart = 0;
56 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
58 if (rValue[i] == '{')
60 if (!nLevel)
61 nStart = i;
62 nLevel++;
64 else if (rValue[i] == '}')
66 nLevel--;
67 if (!nLevel)
69 lcl_parseAdjustmentValue(rAdjustmentValues, rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
75 drawing::EnhancedCustomShapeParameterPair lcl_parseEnhancedCustomShapeParameterPair(const OString& rValue)
77 drawing::EnhancedCustomShapeParameterPair aPair;
78 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 sal_Int32 nIndex = strlen(aExpectedFVPrefix);
83 aPair.First.Value = uno::makeAny(static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32()));
85 static const char aExpectedFTPrefix[] = ", Type = (short) ";
86 aToken = aToken.copy(nIndex);
87 assert(aToken.startsWith(aExpectedFTPrefix));
88 nIndex = strlen(aExpectedFTPrefix);
89 aPair.First.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
91 static const char aExpectedSVPrefix[] = ", Second = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
92 aToken = aToken.copy(nIndex);
93 assert(aToken.startsWith(aExpectedSVPrefix));
94 nIndex = strlen(aExpectedSVPrefix);
95 aPair.Second.Value = uno::makeAny(static_cast<sal_uInt32>(aToken.getToken(0, '}', nIndex).toInt32()));
97 static const char aExpectedSTPrefix[] = ", Type = (short) ";
98 aToken = aToken.copy(nIndex);
99 assert(aToken.startsWith(aExpectedSTPrefix));
100 nIndex = strlen(aExpectedSTPrefix);
101 aPair.Second.Type = static_cast<sal_uInt16>(aToken.getToken(0, '}', nIndex).toInt32());
102 return aPair;
105 drawing::EnhancedCustomShapeSegment lcl_parseEnhancedCustomShapeSegment(const OString& rValue)
107 drawing::EnhancedCustomShapeSegment aSegment;
108 OString aToken = rValue;
109 // We expect the followings here: Command, Count
110 static const char aExpectedCommandPrefix[] = "Command = (short) ";
111 assert(aToken.startsWith(aExpectedCommandPrefix));
112 sal_Int32 nIndex = strlen(aExpectedCommandPrefix);
113 aSegment.Command = static_cast<sal_Int16>(aToken.getToken(0, ',', nIndex).toInt32());
115 static const char aExpectedCountPrefix[] = " Count = (short) ";
116 aToken = aToken.copy(nIndex);
117 assert(aToken.startsWith(aExpectedCountPrefix));
118 nIndex = strlen(aExpectedCountPrefix);
119 aSegment.Count = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
120 return aSegment;
123 awt::Rectangle lcl_parseRectangle(const OString& rValue)
125 awt::Rectangle aRectangle;
126 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 sal_Int32 nIndex = strlen(aExpectedXPrefix);
131 aRectangle.X = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
133 static const char aExpectedYPrefix[] = " Y = (long) ";
134 aToken = aToken.copy(nIndex);
135 assert(aToken.startsWith(aExpectedYPrefix));
136 nIndex = strlen(aExpectedYPrefix);
137 aRectangle.Y = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
139 static const char aExpectedWidthPrefix[] = " Width = (long) ";
140 aToken = aToken.copy(nIndex);
141 assert(aToken.startsWith(aExpectedWidthPrefix));
142 nIndex = strlen(aExpectedWidthPrefix);
143 aRectangle.Width = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
145 static const char aExpectedHeightPrefix[] = " Height = (long) ";
146 aToken = aToken.copy(nIndex);
147 assert(aToken.startsWith(aExpectedHeightPrefix));
148 nIndex = strlen(aExpectedHeightPrefix);
149 aRectangle.Height = static_cast<sal_Int32>(aToken.copy(nIndex).toInt32());
151 return aRectangle;
154 awt::Size lcl_parseSize(const OString& rValue)
156 awt::Size aSize;
157 OString aToken = rValue;
158 // We expect the followings here: Width, Height
159 static const char aExpectedWidthPrefix[] = "Width = (long) ";
160 assert(aToken.startsWith(aExpectedWidthPrefix));
161 sal_Int32 nIndex = strlen(aExpectedWidthPrefix);
162 aSize.Width = static_cast<sal_Int32>(aToken.getToken(0, ',', nIndex).toInt32());
164 static const char aExpectedHeightPrefix[] = " Height = (long) ";
165 aToken = aToken.copy(nIndex);
166 assert(aToken.startsWith(aExpectedHeightPrefix));
167 nIndex = strlen(aExpectedHeightPrefix);
168 aSize.Height = static_cast<sal_Int32>(aToken.copy(nIndex).toInt32());
170 return aSize;
173 drawing::EnhancedCustomShapeTextFrame lcl_parseEnhancedCustomShapeTextFrame(const OString& rValue)
175 drawing::EnhancedCustomShapeTextFrame aTextFrame;
176 sal_Int32 nLevel = 0;
177 bool bIgnore = false;
178 sal_Int32 nStart = 0;
179 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
181 if (rValue[i] == '{')
183 if (!nLevel)
184 bIgnore = true;
185 nLevel++;
187 else if (rValue[i] == '}')
189 nLevel--;
190 if (!nLevel)
191 bIgnore = false;
193 else if (rValue[i] == ',' && !bIgnore)
195 OString aToken = rValue.copy(nStart, i - nStart);
196 static const char aExpectedPrefix[] = "TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
197 if (aToken.startsWith(aExpectedPrefix))
199 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }"));
200 aTextFrame.TopLeft = lcl_parseEnhancedCustomShapeParameterPair(aToken);
202 else
203 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken);
204 nStart = i + strlen(", ");
208 OString aToken = rValue.copy(nStart, rValue.getLength() - nStart);
209 static const char aExpectedPrefix[] = "BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
210 if (aToken.startsWith(aExpectedPrefix))
212 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" }"));
213 aTextFrame.BottomRight = lcl_parseEnhancedCustomShapeParameterPair(aToken);
215 else
216 SAL_WARN("oox", "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken);
218 return aTextFrame;
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 void lcl_parseHandlePosition(std::vector<beans::PropertyValue>& rHandle, const OString& rValue)
225 sal_Int32 nLevel = 0;
226 bool bIgnore = false;
227 sal_Int32 nStart = 0;
228 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
230 if (rValue[i] == '{')
232 if (!nLevel)
233 bIgnore = true;
234 nLevel++;
236 else if (rValue[i] == '}')
238 nLevel--;
239 if (!nLevel)
240 bIgnore = false;
242 else if (rValue[i] == ',' && !bIgnore)
244 OString aToken = rValue.copy(nStart, i - nStart);
245 static const char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
246 if (aToken.startsWith(aExpectedPrefix))
248 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
250 beans::PropertyValue aPropertyValue;
251 aPropertyValue.Name = "Position";
252 aPropertyValue.Value = uno::makeAny(lcl_parseEnhancedCustomShapeParameterPair(aToken));
253 rHandle.push_back(aPropertyValue);
255 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
256 SAL_WARN("oox", "lcl_parseHandlePosition: unexpected token: " << aToken);
257 nStart = i + strlen(", ");
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 void lcl_parseHandleRange(std::vector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
266 sal_Int32 nLevel = 0;
267 bool bIgnore = false;
268 sal_Int32 nStart = 0;
269 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
271 if (rValue[i] == '{')
273 if (!nLevel)
274 bIgnore = true;
275 nLevel++;
277 else if (rValue[i] == '}')
279 nLevel--;
280 if (!nLevel)
281 bIgnore = false;
283 else if (rValue[i] == ',' && !bIgnore)
285 OString aToken = rValue.copy(nStart, i - nStart);
286 static const char aExpectedPrefix[] = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { ";
287 if (aToken.startsWith(aExpectedPrefix))
289 drawing::EnhancedCustomShapeParameter aParameter;
290 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 sal_Int32 nIndex = strlen(aExpectedVPrefix);
295 aParameter.Value = uno::makeAny(aToken.getToken(0, '}', nIndex).toInt32());
297 static const char aExpectedTPrefix[] = ", Type = (short) ";
298 aToken = aToken.copy(nIndex);
299 assert(aToken.startsWith(aExpectedTPrefix));
300 nIndex = strlen(aExpectedTPrefix);
301 aParameter.Type = static_cast<sal_Int16>(aToken.getToken(0, '}', nIndex).toInt32());
303 beans::PropertyValue aPropertyValue;
304 aPropertyValue.Name = rName;
305 aPropertyValue.Value = uno::makeAny(aParameter);
306 rHandle.push_back(aPropertyValue);
309 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
310 SAL_WARN("oox", "lcl_parseHandleRange: unexpected token: " << aToken);
311 nStart = i + strlen(", ");
316 // Parses a string like: Name = "RefY", Handle = (long) 0, Value = (any) { (long) 0 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
317 void lcl_parseHandleRef(std::vector<beans::PropertyValue>& rHandle, const OString& rValue, const OUString& rName)
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 if (rValue.startsWith(aExpectedXPrefix) || rValue.startsWith(aExpectedYPrefix))
323 sal_Int32 nIndex = strlen(aExpectedXPrefix);
324 beans::PropertyValue aPropertyValue;
325 aPropertyValue.Name = rName;
326 // We only expect a Value here
327 aPropertyValue.Value = uno::makeAny(rValue.getToken(0, '}', nIndex).toInt32());
328 rHandle.push_back(aPropertyValue);
330 else
331 SAL_WARN("oox", "lcl_parseHandleRef: unexpected value: " << rValue);
334 uno::Sequence<beans::PropertyValue> lcl_parseHandle(const OString& rValue)
336 std::vector<beans::PropertyValue> aRet;
337 sal_Int32 nLevel = 0;
338 sal_Int32 nStart = 0;
339 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
341 if (rValue[i] == '{')
343 if (!nLevel)
344 nStart = i;
345 nLevel++;
347 else if (rValue[i] == '}')
349 nLevel--;
350 if (!nLevel)
352 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
353 if (aToken.startsWith("Name = \"Position\""))
354 lcl_parseHandlePosition(aRet, aToken);
355 else if (aToken.startsWith("Name = \"RangeXMaximum\""))
356 lcl_parseHandleRange(aRet, aToken, "RangeXMaximum");
357 else if (aToken.startsWith("Name = \"RangeXMinimum\""))
358 lcl_parseHandleRange(aRet, aToken, "RangeXMinimum");
359 else if (aToken.startsWith("Name = \"RangeYMaximum\""))
360 lcl_parseHandleRange(aRet, aToken, "RangeYMaximum");
361 else if (aToken.startsWith("Name = \"RangeYMinimum\""))
362 lcl_parseHandleRange(aRet, aToken, "RangeYMinimum");
363 else if (aToken.startsWith("Name = \"RadiusRangeMaximum\""))
364 lcl_parseHandleRange(aRet, aToken, "RadiusRangeMaximum");
365 else if (aToken.startsWith("Name = \"RadiusRangeMinimum\""))
366 lcl_parseHandleRange(aRet, aToken, "RadiusRangeMinimum");
367 else if (aToken.startsWith("Name = \"RefX\""))
368 lcl_parseHandleRef(aRet, aToken, "RefX");
369 else if (aToken.startsWith("Name = \"RefY\""))
370 lcl_parseHandleRef(aRet, aToken, "RefY");
371 else
372 SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken);
376 return comphelper::containerToSequence(aRet);
379 void lcl_parseHandles(std::vector< uno::Sequence<beans::PropertyValue> >& rHandles, const OString& rValue)
381 sal_Int32 nLevel = 0;
382 sal_Int32 nStart = 0;
383 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
385 if (rValue[i] == '{')
387 if (!nLevel)
388 nStart = i;
389 nLevel++;
391 else if (rValue[i] == '}')
393 nLevel--;
394 if (!nLevel)
396 uno::Sequence<beans::PropertyValue> aHandle = lcl_parseHandle(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },")));
397 rHandles.push_back(aHandle);
403 void lcl_parseEquations(std::vector<OUString>& rEquations, const OString& rValue)
405 bool bInString = false;
406 sal_Int32 nStart = 0;
407 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
409 if (rValue[i] == '"' && !bInString)
411 nStart = i;
412 bInString = true;
414 else if (rValue[i] == '"' && bInString)
416 bInString = false;
417 rEquations.push_back(OUString::fromUtf8(rValue.copy(nStart + strlen("\""), i - nStart - strlen("\""))));
422 void lcl_parsePathCoordinateValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
424 std::vector<drawing::EnhancedCustomShapeParameterPair> aPairs;
425 sal_Int32 nLevel = 0;
426 sal_Int32 nStart = 0;
427 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
429 if (rValue[i] == '{')
431 if (!nLevel)
432 nStart = i;
433 nLevel++;
435 else if (rValue[i] == '}')
437 nLevel--;
438 if (!nLevel)
439 aPairs.push_back(lcl_parseEnhancedCustomShapeParameterPair(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
443 beans::PropertyValue aPropertyValue;
444 aPropertyValue.Name = "Coordinates";
445 aPropertyValue.Value = uno::makeAny(comphelper::containerToSequence(aPairs));
446 rPath.push_back(aPropertyValue);
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 void lcl_parsePathCoordinates(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
453 sal_Int32 nLevel = 0;
454 bool bIgnore = false;
455 sal_Int32 nStart = 0;
456 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
458 if (rValue[i] == '{')
460 if (!nLevel)
461 bIgnore = true;
462 nLevel++;
464 else if (rValue[i] == '}')
466 nLevel--;
467 if (!nLevel)
468 bIgnore = false;
470 else if (rValue[i] == ',' && !bIgnore)
472 OString aToken = rValue.copy(nStart, i - nStart);
473 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
474 if (aToken.startsWith(aExpectedPrefix))
476 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
477 lcl_parsePathCoordinateValues(rPath, aToken);
479 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
480 SAL_WARN("oox", "lcl_parsePathCoordinates: unexpected token: " << aToken);
481 nStart = i + strlen(", ");
486 void lcl_parsePathSegmentValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
488 std::vector<drawing::EnhancedCustomShapeSegment> aSegments;
489 sal_Int32 nLevel = 0;
490 sal_Int32 nStart = 0;
491 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
493 if (rValue[i] == '{')
495 if (!nLevel)
496 nStart = i;
497 nLevel++;
499 else if (rValue[i] == '}')
501 nLevel--;
502 if (!nLevel)
503 aSegments.push_back(lcl_parseEnhancedCustomShapeSegment(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
507 beans::PropertyValue aPropertyValue;
508 aPropertyValue.Name = "Segments";
509 aPropertyValue.Value = uno::makeAny(comphelper::containerToSequence(aSegments));
510 rPath.push_back(aPropertyValue);
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 void lcl_parsePathSegments(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
517 sal_Int32 nLevel = 0;
518 bool bIgnore = false;
519 sal_Int32 nStart = 0;
520 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
522 if (rValue[i] == '{')
524 if (!nLevel)
525 bIgnore = true;
526 nLevel++;
528 else if (rValue[i] == '}')
530 nLevel--;
531 if (!nLevel)
532 bIgnore = false;
534 else if (rValue[i] == ',' && !bIgnore)
536 OString aToken = rValue.copy(nStart, i - nStart);
537 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { ";
538 if (aToken.startsWith(aExpectedPrefix))
540 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
541 lcl_parsePathSegmentValues(rPath, aToken);
543 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
544 SAL_WARN("oox", "lcl_parsePathSegments: unexpected token: " << aToken);
545 nStart = i + strlen(", ");
550 void lcl_parsePathTextFrameValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
552 std::vector<drawing::EnhancedCustomShapeTextFrame> aTextFrames;
553 sal_Int32 nLevel = 0;
554 sal_Int32 nStart = 0;
555 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
557 if (rValue[i] == '{')
559 if (!nLevel)
560 nStart = i;
561 nLevel++;
563 else if (rValue[i] == '}')
565 nLevel--;
566 if (!nLevel)
567 aTextFrames.push_back(lcl_parseEnhancedCustomShapeTextFrame(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
571 beans::PropertyValue aPropertyValue;
572 aPropertyValue.Name = "TextFrames";
573 aPropertyValue.Value = uno::makeAny(comphelper::containerToSequence(aTextFrames));
574 rPath.push_back(aPropertyValue);
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 void lcl_parsePathTextFrames(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
581 sal_Int32 nLevel = 0;
582 bool bIgnore = false;
583 sal_Int32 nStart = 0;
584 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
586 if (rValue[i] == '{')
588 if (!nLevel)
589 bIgnore = true;
590 nLevel++;
592 else if (rValue[i] == '}')
594 nLevel--;
595 if (!nLevel)
596 bIgnore = false;
598 else if (rValue[i] == ',' && !bIgnore)
600 OString aToken = rValue.copy(nStart, i - nStart);
601 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { ";
602 if (aToken.startsWith(aExpectedPrefix))
604 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
605 lcl_parsePathTextFrameValues(rPath, aToken);
607 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
608 SAL_WARN("oox", "lcl_parsePathTextFrames: unexpected token: " << aToken);
609 nStart = i + strlen(", ");
614 void lcl_parsePathSubViewSizeValues(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
616 std::vector<awt::Size> aSizes;
617 sal_Int32 nLevel = 0;
618 sal_Int32 nStart = 0;
619 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
621 if (rValue[i] == '{')
623 if (!nLevel)
624 nStart = i;
625 nLevel++;
627 else if (rValue[i] == '}')
629 nLevel--;
630 if (!nLevel)
631 aSizes.push_back(lcl_parseSize(rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"))));
635 beans::PropertyValue aPropertyValue;
636 aPropertyValue.Name = "SubViewSize";
637 aPropertyValue.Value = uno::makeAny(comphelper::containerToSequence(aSizes));
638 rPath.push_back(aPropertyValue);
641 void lcl_parsePathSubViewSize(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
643 sal_Int32 nLevel = 0;
644 bool bIgnore = false;
645 sal_Int32 nStart = 0;
646 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
648 if (rValue[i] == '{')
650 if (!nLevel)
651 bIgnore = true;
652 nLevel++;
654 else if (rValue[i] == '}')
656 nLevel--;
657 if (!nLevel)
658 bIgnore = false;
660 else if (rValue[i] == ',' && !bIgnore)
662 OString aToken = rValue.copy(nStart, i - nStart);
663 static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.awt.Size) { ";
664 if (aToken.startsWith(aExpectedPrefix))
666 aToken = aToken.copy(strlen(aExpectedPrefix), aToken.getLength() - strlen(aExpectedPrefix) - strlen(" } }"));
667 lcl_parsePathSubViewSizeValues(rPath, aToken);
669 else if (!aToken.startsWith("Name =") && !aToken.startsWith("Handle ="))
670 SAL_WARN("oox", "lcl_parsePathSubViewSize: unexpected token: " << aToken);
671 nStart = i + strlen(", ");
676 void lcl_parsePath(std::vector<beans::PropertyValue>& rPath, const OString& rValue)
678 sal_Int32 nLevel = 0;
679 sal_Int32 nStart = 0;
680 for (sal_Int32 i = 0; i < rValue.getLength(); ++i)
682 if (rValue[i] == '{')
684 if (!nLevel)
685 nStart = i;
686 nLevel++;
688 else if (rValue[i] == '}')
690 nLevel--;
691 if (!nLevel)
693 OString aToken = rValue.copy(nStart + strlen("{ "), i - nStart - strlen(" },"));
694 if (aToken.startsWith("Name = \"Coordinates\""))
695 lcl_parsePathCoordinates(rPath, aToken);
696 else if (aToken.startsWith("Name = \"Segments\""))
697 lcl_parsePathSegments(rPath, aToken);
698 else if (aToken.startsWith("Name = \"TextFrames\""))
699 lcl_parsePathTextFrames(rPath, aToken);
700 else if (aToken.startsWith("Name = \"SubViewSize\""))
701 lcl_parsePathSubViewSize(rPath, aToken);
702 else
703 SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken);
711 namespace oox
713 namespace drawingml
716 void CustomShapeProperties::initializePresetDataMap()
718 OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/oox-drawingml-cs-presets");
719 rtl::Bootstrap::expandMacros(aPath);
720 SvFileStream aStream(aPath, StreamMode::READ);
721 if (aStream.GetError() != ERRCODE_NONE)
722 SAL_WARN("oox", "failed to open oox-drawingml-cs-presets");
723 OString aLine;
724 OUString aName;
725 bool bNotDone = aStream.ReadLine(aLine);
726 PropertyMap aPropertyMap;
727 bool bFirst = true;
728 while (bNotDone)
730 static const char aCommentPrefix[] = "/* ";
731 if (aLine.startsWith(aCommentPrefix))
733 if (bFirst)
734 bFirst = false;
735 else
736 maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
737 aName = OUString::fromUtf8(aLine.copy(strlen(aCommentPrefix), aLine.getLength() - strlen(aCommentPrefix) - strlen(" */")));
739 else
741 if (aLine == "AdjustmentValues")
743 aStream.ReadLine(aLine);
744 if (aLine != "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}")
746 std::vector<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustmentValues;
747 OString aExpectedPrefix("([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { ");
748 assert(aLine.startsWith(aExpectedPrefix));
750 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
751 lcl_parseAdjustmentValues(aAdjustmentValues, aValue);
752 aPropertyMap.setProperty(PROP_AdjustmentValues, comphelper::containerToSequence(aAdjustmentValues));
754 else
755 aPropertyMap.setProperty(PROP_AdjustmentValues, uno::Sequence<OUString>(0));
757 else if (aLine == "Equations")
759 aStream.ReadLine(aLine);
760 if (aLine != "([]string) {}")
762 std::vector<OUString> aEquations;
763 OString aExpectedPrefix("([]string) { ");
764 assert(aLine.startsWith(aExpectedPrefix));
766 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
767 lcl_parseEquations(aEquations, aValue);
768 aPropertyMap.setProperty(PROP_Equations, comphelper::containerToSequence(aEquations));
770 else
771 aPropertyMap.setProperty(PROP_Equations, uno::Sequence<OUString>(0));
773 else if (aLine == "Handles")
775 aStream.ReadLine(aLine);
776 if (aLine != "([][]com.sun.star.beans.PropertyValue) {}")
778 std::vector< uno::Sequence<beans::PropertyValue> > aHandles;
779 OString aExpectedPrefix("([][]com.sun.star.beans.PropertyValue) { ");
780 assert(aLine.startsWith(aExpectedPrefix));
782 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
783 lcl_parseHandles(aHandles, aValue);
784 aPropertyMap.setProperty(PROP_Handles, comphelper::containerToSequence(aHandles));
786 else
787 aPropertyMap.setProperty(PROP_Handles, uno::Sequence<OUString>(0));
789 else if (aLine == "MirroredX")
791 aStream.ReadLine(aLine);
792 if (aLine == "true" || aLine == "false")
794 aPropertyMap.setProperty(PROP_MirroredX, aLine == "true");
796 else
797 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredX parameter");
799 else if (aLine == "MirroredY")
801 aStream.ReadLine(aLine);
802 if (aLine == "true" || aLine == "false")
804 aPropertyMap.setProperty(PROP_MirroredY, aLine == "true");
806 else
807 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected MirroredY parameter");
809 else if (aLine == "Path")
811 aStream.ReadLine(aLine);
812 OString aExpectedPrefix("([]com.sun.star.beans.PropertyValue) { ");
813 assert(aLine.startsWith(aExpectedPrefix));
815 std::vector<beans::PropertyValue> aPathValue;
816 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
817 lcl_parsePath(aPathValue, aValue);
818 aPropertyMap.setProperty(PROP_Path, comphelper::containerToSequence(aPathValue));
820 else if (aLine == "Type")
822 // Just ignore the line here, we already know the correct type.
823 aStream.ReadLine(aLine);
824 aPropertyMap.setProperty(PROP_Type, "ooxml-" + aName);
826 else if (aLine == "ViewBox")
828 aStream.ReadLine(aLine);
829 OString aExpectedPrefix("(com.sun.star.awt.Rectangle) { ");
830 assert(aLine.startsWith(aExpectedPrefix));
832 OString aValue = aLine.copy(aExpectedPrefix.getLength(), aLine.getLength() - aExpectedPrefix.getLength() - strlen(" }"));
833 aPropertyMap.setProperty(PROP_ViewBox, lcl_parseRectangle(aValue));
835 else
836 SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unhandled line: " << aLine);
838 bNotDone = aStream.ReadLine(aLine);
840 maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
846 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */