Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / oox / source / drawingml / customshapegeometry.cxx
blob5991b0a6032292de6d2d5439b3ab65daf137506b
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <drawingml/customshapegeometry.hxx>
21 #include <drawingml/customshapeproperties.hxx>
23 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
24 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
25 #include <com/sun/star/xml/sax/FastToken.hpp>
26 #include <osl/diagnose.h>
27 #include <sal/log.hxx>
28 #include <oox/helper/helper.hxx>
29 #include <oox/helper/attributelist.hxx>
30 #include <oox/helper/propertymap.hxx>
31 #include <oox/token/namespaces.hxx>
32 #include <oox/token/tokens.hxx>
33 #include <unordered_map>
35 using namespace ::oox::core;
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::drawing;
38 using namespace ::com::sun::star::xml::sax;
40 namespace oox { namespace drawingml {
42 enum FormularCommand
44 FC_MULDIV = 0,
45 FC_PLUSMINUS,
46 FC_PLUSDIV,
47 FC_IFELSE,
48 FC_IFELSE1,
49 FC_ABS,
50 FC_AT2,
51 FC_CAT2,
52 FC_COS,
53 FC_MAX,
54 FC_MIN,
55 FC_MOD,
56 FC_PIN,
57 FC_SAT2,
58 FC_SIN,
59 FC_SQRT,
60 FC_TAN,
61 FC_VAL
63 struct FormularCommandNameTable
65 const char* pS;
66 FormularCommand const pE;
68 static const FormularCommandNameTable pFormularCommandNameTable[] =
70 { "*/", FC_MULDIV },
71 { "+-", FC_PLUSMINUS },
72 { "+/", FC_PLUSDIV },
73 { "ifelse", FC_IFELSE },
74 { "?:", FC_IFELSE1 },
75 { "abs", FC_ABS },
76 { "at2", FC_AT2 },
77 { "cat2", FC_CAT2 },
78 { "cos", FC_COS },
79 { "max", FC_MAX },
80 { "min", FC_MIN },
81 { "mod", FC_MOD },
82 { "pin", FC_PIN },
83 { "sat2", FC_SAT2 },
84 { "sin", FC_SIN },
85 { "sqrt", FC_SQRT },
86 { "tan", FC_TAN },
87 { "val", FC_VAL }
90 typedef std::unordered_map< OUString, FormularCommand > FormulaCommandHMap;
92 static const FormulaCommandHMap* pCommandHashMap;
94 static OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
96 OUString aRet;
97 switch( rParameter.Type )
99 case EnhancedCustomShapeParameterType::NORMAL :
101 if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
103 double fValue = 0.0;
104 if ( rParameter.Value >>= fValue )
105 aRet = OUString::number( fValue );
107 else
109 sal_Int32 nValue = 0;
110 if ( rParameter.Value >>= nValue )
111 aRet = OUString::number( nValue );
114 break;
115 case EnhancedCustomShapeParameterType::EQUATION :
117 if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
119 sal_Int32 nFormulaIndex;
120 if ( rParameter.Value >>= nFormulaIndex )
122 aRet = "?"
123 + OUString::number( nFormulaIndex )
124 + " ";
127 else
129 // ups... we should have an index here and not the formula name
132 break;
133 case EnhancedCustomShapeParameterType::ADJUSTMENT :
135 if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
137 sal_Int32 nAdjustmentIndex;
138 if ( rParameter.Value >>= nAdjustmentIndex )
140 aRet = "$"
141 + OUString::number( nAdjustmentIndex )
142 + " ";
145 else
147 // ups... we should have an index here and not the formula name
150 break;
151 case EnhancedCustomShapeParameterType::LEFT :
152 aRet = "left";
153 break;
154 case EnhancedCustomShapeParameterType::TOP :
155 aRet = "top";
156 break;
157 case EnhancedCustomShapeParameterType::RIGHT :
158 aRet = "right";
159 break;
160 case EnhancedCustomShapeParameterType::BOTTOM :
161 aRet = "bottom";
162 break;
163 case EnhancedCustomShapeParameterType::XSTRETCH :
164 aRet = "xstretch";
165 break;
166 case EnhancedCustomShapeParameterType::YSTRETCH :
167 aRet = "ystretch";
168 break;
169 case EnhancedCustomShapeParameterType::HASSTROKE :
170 aRet = "hasstroke";
171 break;
172 case EnhancedCustomShapeParameterType::HASFILL :
173 aRet = "hasfill";
174 break;
175 case EnhancedCustomShapeParameterType::WIDTH :
176 aRet = "width";
177 break;
178 case EnhancedCustomShapeParameterType::HEIGHT :
179 aRet = "height";
180 break;
181 case EnhancedCustomShapeParameterType::LOGWIDTH :
182 aRet = "logwidth";
183 break;
184 case EnhancedCustomShapeParameterType::LOGHEIGHT :
185 aRet = "logheight";
186 break;
188 return aRet;
191 static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const OUString& rValue, bool bNoSymbols = true )
193 css::drawing::EnhancedCustomShapeParameter aRet;
194 if ( !rValue.isEmpty() )
196 bool bConstant = true;
197 sal_Int32 nConstant = -1;
198 sal_Int32 nIntVal = 0;
200 // first check if it's a constant value
201 switch( AttributeConversion::decodeToken( rValue ) )
203 case XML_3cd4 : nConstant = 270 * 60000; break;
204 case XML_3cd8 : nConstant = 135 * 60000; break;
205 case XML_5cd8 : nConstant = 225 * 60000; break;
206 case XML_7cd8 : nConstant = 315 * 60000; break;
207 case XML_cd2 : nConstant = 180 * 60000; break;
208 case XML_cd3 : nConstant = 120 * 60000; break;
209 case XML_cd4 : nConstant = 90 * 60000; break;
210 case XML_cd8 : nConstant = 45 * 60000; break;
212 case XML_b : // variable height of the shape defined in spPr
213 case XML_h :
215 if ( bNoSymbols )
217 CustomShapeGuide aGuide;
218 aGuide.maName = rValue;
219 aGuide.maFormula = "logheight" ;
221 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
222 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
224 else
225 aRet.Type = EnhancedCustomShapeParameterType::LOGHEIGHT; // TODO: HEIGHT needs to be implemented
227 break;
229 case XML_hd10 :
230 nIntVal += 2; // */ h 1.0 10.0
231 [[fallthrough]];
232 case XML_hd8 : // */ h 1.0 8.0
233 nIntVal += 2;
234 [[fallthrough]];
235 case XML_hd6 : // */ h 1.0 6.0
236 nIntVal++;
237 [[fallthrough]];
238 case XML_hd5 : // */ h 1.0 5.0
239 nIntVal++;
240 [[fallthrough]];
241 case XML_hd4 : // */ h 1.0 4.0
242 nIntVal++;
243 [[fallthrough]];
244 case XML_hd3 : // */ h 1.0 3.0
245 nIntVal++;
246 [[fallthrough]];
247 case XML_hd2 : // */ h 1.0 2.0
248 case XML_vc : // */ h 1.0 2.0
250 nIntVal += 2;
252 CustomShapeGuide aGuide;
253 aGuide.maName = rValue;
254 aGuide.maFormula = "logheight/" + OUString::number( nIntVal );
256 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
257 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
259 break;
261 case XML_t :
262 case XML_l :
264 nConstant = 0;
265 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
267 break;
269 case XML_ls : // longest side: max w h
271 CustomShapeGuide aGuide;
272 aGuide.maName = rValue;
273 aGuide.maFormula = "max(logwidth,logheight)";
275 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
276 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
278 break;
279 case XML_ss : // shortest side: min w h
281 CustomShapeGuide aGuide;
282 aGuide.maName = rValue;
283 aGuide.maFormula = "min(logwidth,logheight)";
285 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
286 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
288 break;
289 case XML_ssd32 : // */ ss 1.0 32.0
290 nIntVal += 16;
291 [[fallthrough]];
292 case XML_ssd16 : // */ ss 1.0 16.0
293 nIntVal += 8;
294 [[fallthrough]];
295 case XML_ssd8 : // */ ss 1.0 8.0
296 nIntVal += 2;
297 [[fallthrough]];
298 case XML_ssd6 : // */ ss 1.0 6.0
299 nIntVal += 2;
300 [[fallthrough]];
301 case XML_ssd4 : // */ ss 1.0 4.0
302 nIntVal += 2;
303 [[fallthrough]];
304 case XML_ssd2 : // */ ss 1.0 2.0
306 nIntVal += 2;
308 CustomShapeGuide aGuide;
309 aGuide.maName = rValue;
310 aGuide.maFormula = "min(logwidth,logheight)/" + OUString::number( nIntVal );
312 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
313 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
315 break;
317 case XML_r : // variable width of the shape defined in spPr
318 case XML_w :
320 if ( bNoSymbols )
322 CustomShapeGuide aGuide;
323 aGuide.maName = rValue;
324 aGuide.maFormula = "logwidth" ;
326 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
327 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
329 else
330 aRet.Type = EnhancedCustomShapeParameterType::LOGWIDTH;
332 break;
334 case XML_wd32 : // */ w 1.0 32.0
335 nIntVal += 20;
336 [[fallthrough]];
337 case XML_wd12 : // */ w 1.0 12.0
338 nIntVal += 2;
339 [[fallthrough]];
340 case XML_wd10 : // */ w 1.0 10.0
341 nIntVal += 2;
342 [[fallthrough]];
343 case XML_wd8 : // */ w 1.0 8.0
344 nIntVal += 2;
345 [[fallthrough]];
346 case XML_wd6 : // */ w 1.0 6.0
347 nIntVal++;
348 [[fallthrough]];
349 case XML_wd5 : // */ w 1.0 5.0
350 nIntVal++;
351 [[fallthrough]];
352 case XML_wd4 : // */ w 1.0 4.0
353 nIntVal++;
354 [[fallthrough]];
355 case XML_wd3 : // */ w 1.0 3.0
356 nIntVal++;
357 [[fallthrough]];
358 case XML_hc : // */ w 1.0 2.0
359 case XML_wd2 : // */ w 1.0 2.0
361 nIntVal += 2;
363 CustomShapeGuide aGuide;
364 aGuide.maName = rValue;
365 aGuide.maFormula = "logwidth/" + OUString::number( nIntVal );
367 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
368 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
370 break;
372 default:
373 bConstant = false;
374 break;
376 if ( bConstant )
378 if (nConstant != -1) {
379 aRet.Value <<= nConstant;
380 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
383 else
385 sal_Unicode n = rValue[ 0 ];
386 if ( ( n == '+' ) || ( n == '-' ) )
388 if ( rValue.getLength() > 1 )
389 n = rValue[ 1 ];
391 if ( ( n >= '0' ) && ( n <= '9' ) )
392 { // seems to be a ST_Coordinate
393 aRet.Value <<= rValue.toInt32();
394 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
396 else
398 sal_Int32 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getAdjustmentGuideList(), rValue );
399 if ( nGuideIndex >= 0 )
401 aRet.Value <<= nGuideIndex;
402 aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
404 else
406 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), rValue );
407 if ( nGuideIndex >= 0 )
409 aRet.Value <<= nGuideIndex;
410 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
412 else
414 SAL_WARN("oox", "error: unhandled value " << rValue);
415 aRet.Value <<= rValue;
421 return aRet;
424 // CT_GeomGuideList
425 class GeomGuideListContext : public ContextHandler2
427 public:
428 GeomGuideListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList );
429 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
431 protected:
432 std::vector< CustomShapeGuide >& mrGuideList;
433 CustomShapeProperties& mrCustomShapeProperties;
436 GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList )
437 : ContextHandler2( rParent )
438 , mrGuideList( rGuideList )
439 , mrCustomShapeProperties( rCustomShapeProperties )
443 static OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, const OUString& rSource )
445 if ( !pCommandHashMap )
447 FormulaCommandHMap* pHM = new FormulaCommandHMap;
448 for(const FormularCommandNameTable& i : pFormularCommandNameTable)
449 (*pHM)[ OUString::createFromAscii( i.pS ) ] = i.pE;
450 pCommandHashMap = pHM;
453 std::vector< OUString > aTokens;
454 sal_Int32 nIndex = 0;
457 OUString aToken( rSource.getToken( 0, ' ', nIndex ) );
458 if ( !aToken.isEmpty() )
459 aTokens.push_back( aToken );
461 while ( nIndex >= 0 );
463 OUString aEquation;
464 if ( !aTokens.empty() )
466 sal_Int32 i, nParameters = aTokens.size() - 1;
467 if ( nParameters > 3 )
468 nParameters = 3;
470 OUString sParameters[ 3 ];
472 for ( i = 0; i < nParameters; i++ )
473 sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], false ) );
475 const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
476 if ( aIter != pCommandHashMap->end() )
478 switch( aIter->second )
480 case FC_MULDIV :
482 if ( nParameters == 3 )
483 aEquation = sParameters[ 0 ] + "*" + sParameters[ 1 ]
484 + "/" + sParameters[ 2 ];
486 break;
487 case FC_PLUSMINUS :
489 if ( nParameters == 3 )
490 aEquation = sParameters[ 0 ] + "+" + sParameters[ 1 ]
491 + "-" + sParameters[ 2 ];
493 break;
494 case FC_PLUSDIV :
496 if ( nParameters == 3 )
497 aEquation = "(" + sParameters[ 0 ] + "+"
498 + sParameters[ 1 ] + ")/" + sParameters[ 2 ];
500 break;
501 case FC_IFELSE :
502 case FC_IFELSE1 :
504 if ( nParameters == 3 )
505 aEquation = "if(" + sParameters[ 0 ] + ","
506 + sParameters[ 1 ] + "," + sParameters[ 2 ] + ")";
508 break;
509 case FC_ABS :
511 if ( nParameters == 1 )
512 aEquation = "abs(" + sParameters[ 0 ] + ")";
514 break;
515 case FC_AT2 :
517 if ( nParameters == 2 )
518 aEquation = "(10800000*atan2(" + sParameters[ 1 ] + ","
519 + sParameters[ 0 ] + "))/pi";
521 break;
522 case FC_CAT2 :
524 if ( nParameters == 3 )
525 aEquation = sParameters[ 0 ] + "*(cos(atan2(" +
526 sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
528 break;
529 case FC_COS :
531 if ( nParameters == 2 )
532 aEquation = sParameters[ 0 ] + "*cos(pi*(" +
533 sParameters[ 1 ] + ")/10800000)";
535 break;
536 case FC_MAX :
538 if ( nParameters == 2 )
539 aEquation = "max(" + sParameters[ 0 ] + "," +
540 sParameters[ 1 ] + ")";
542 break;
543 case FC_MIN :
545 if ( nParameters == 2 )
546 aEquation = "min(" + sParameters[ 0 ] + "," +
547 sParameters[ 1 ] + ")";
549 break;
550 case FC_MOD :
552 if ( nParameters == 3 )
553 aEquation = "sqrt("
554 + sParameters[ 0 ] + "*" + sParameters[ 0 ] + "+"
555 + sParameters[ 1 ] + "*" + sParameters[ 1 ] + "+"
556 + sParameters[ 2 ] + "*" + sParameters[ 2 ] + ")";
558 break;
559 case FC_PIN :
561 if ( nParameters == 3 ) // if(x-y,x,if(y-z,z,y))
562 aEquation = "if(" + sParameters[ 0 ] + "-" + sParameters[ 1 ]
563 + "," + sParameters[ 0 ] + ",if(" + sParameters[ 2 ]
564 + "-" + sParameters[ 1 ] + "," + sParameters[ 1 ]
565 + "," + sParameters[ 2 ] + "))";
567 break;
568 case FC_SAT2 :
570 if ( nParameters == 3 )
571 aEquation = sParameters[ 0 ] + "*(sin(atan2(" +
572 sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
574 break;
575 case FC_SIN :
577 if ( nParameters == 2 )
578 aEquation = sParameters[ 0 ] + "*sin(pi*(" +
579 sParameters[ 1 ] + ")/10800000)";
581 break;
582 case FC_SQRT :
584 if ( nParameters == 1 )
585 aEquation = "sqrt(" + sParameters[ 0 ] + ")";
587 break;
588 case FC_TAN :
590 if ( nParameters == 2 )
591 aEquation = sParameters[ 0 ] + "*tan(pi*(" +
592 sParameters[ 1 ] + ")/10800000)";
594 break;
595 case FC_VAL :
597 if ( nParameters == 1 )
598 aEquation = sParameters[ 0 ];
600 break;
601 default :
602 break;
606 return aEquation;
609 ContextHandlerRef GeomGuideListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
611 if ( aElementToken == A_TOKEN( gd ) ) // CT_GeomGuide
613 CustomShapeGuide aGuide;
614 aGuide.maName = rAttribs.getString( XML_name ).get();
615 aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, rAttribs.getString( XML_fmla ).get() );
616 mrGuideList.push_back( aGuide );
618 return this;
621 static const OUString& GetGeomGuideName( const OUString& rValue )
623 return rValue;
626 // CT_AdjPoint2D
627 class AdjPoint2DContext : public ContextHandler2
629 public:
630 AdjPoint2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
633 AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
634 : ContextHandler2( rParent )
636 rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_x ).get() );
637 rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_y ).get() );
640 // CT_XYAdjustHandle
641 class XYAdjustHandleContext : public ContextHandler2
643 public:
644 XYAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
645 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
647 protected:
648 AdjustHandle& mrAdjustHandle;
649 CustomShapeProperties& mrCustomShapeProperties;
652 XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
653 : ContextHandler2( rParent )
654 , mrAdjustHandle( rAdjustHandle )
655 , mrCustomShapeProperties( rCustomShapeProperties )
657 if ( rAttribs.hasAttribute( XML_gdRefX ) )
659 mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefX, "" ) );
661 if ( rAttribs.hasAttribute( XML_minX ) )
663 mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minX, "" ) );
665 if ( rAttribs.hasAttribute( XML_maxX ) )
667 mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxX, "" ) );
669 if ( rAttribs.hasAttribute( XML_gdRefY ) )
671 mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefY, "" ) );
673 if ( rAttribs.hasAttribute( XML_minY ) )
675 mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minY, "" ) );
677 if ( rAttribs.hasAttribute( XML_maxY ) )
679 mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxY, "" ) );
683 ContextHandlerRef XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
685 if ( aElementToken == A_TOKEN( pos ) )
686 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
687 return nullptr;
690 // CT_PolarAdjustHandle
691 class PolarAdjustHandleContext : public ContextHandler2
693 public:
694 PolarAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
695 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
697 protected:
698 AdjustHandle& mrAdjustHandle;
699 CustomShapeProperties& mrCustomShapeProperties;
702 PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
703 : ContextHandler2( rParent )
704 , mrAdjustHandle( rAdjustHandle )
705 , mrCustomShapeProperties( rCustomShapeProperties )
707 if ( rAttribs.hasAttribute( XML_gdRefR ) )
709 mrAdjustHandle.polar = true ;
710 mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefR, "" ) );
712 if ( rAttribs.hasAttribute( XML_minR ) )
714 mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minR, "" ) );
716 if ( rAttribs.hasAttribute( XML_maxR ) )
718 mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxR, "" ) );
720 if ( rAttribs.hasAttribute( XML_gdRefAng ) )
722 mrAdjustHandle.polar = true ;
723 mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefAng, "" ) );
725 if ( rAttribs.hasAttribute( XML_minAng ) )
727 mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minAng, "" ) );
729 if ( rAttribs.hasAttribute( XML_maxAng ) )
731 mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxAng, "" ) );
735 ContextHandlerRef PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
737 // mrAdjustHandle.pos uses planar coordinates.
738 if ( aElementToken == A_TOKEN( pos ) )
739 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
740 return nullptr;
743 // CT_AdjustHandleList
744 class AdjustHandleListContext : public ContextHandler2
746 public:
747 AdjustHandleListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList );
748 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
750 protected:
751 std::vector< AdjustHandle >& mrAdjustHandleList;
752 CustomShapeProperties& mrCustomShapeProperties;
755 AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
756 : ContextHandler2( rParent )
757 , mrAdjustHandleList( rAdjustHandleList )
758 , mrCustomShapeProperties( rCustomShapeProperties )
762 ContextHandlerRef AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
764 if ( aElementToken == A_TOKEN( ahXY ) ) // CT_XYAdjustHandle
766 AdjustHandle aAdjustHandle( false );
767 mrAdjustHandleList.push_back( aAdjustHandle );
768 return new XYAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
770 else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
772 AdjustHandle aAdjustHandle( true );
773 mrAdjustHandleList.push_back( aAdjustHandle );
774 return new PolarAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
776 return nullptr;
779 // CT_ConnectionSite
780 class ConnectionSiteContext : public ContextHandler2
782 public:
783 ConnectionSiteContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite );
784 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
786 protected:
787 ConnectionSite& mrConnectionSite;
788 CustomShapeProperties& mrCustomShapeProperties;
791 ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
792 : ContextHandler2( rParent )
793 , mrConnectionSite( rConnectionSite )
794 , mrCustomShapeProperties( rCustomShapeProperties )
796 mrConnectionSite.ang = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_ang ).get() );
799 ContextHandlerRef ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
801 if ( aElementToken == A_TOKEN( pos ) )
802 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
803 return nullptr;
806 // CT_Path2DMoveTo
807 class Path2DMoveToContext : public ContextHandler2
809 public:
810 Path2DMoveToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
811 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
813 protected:
814 EnhancedCustomShapeParameterPair& mrAdjPoint2D;
815 CustomShapeProperties& mrCustomShapeProperties;
818 Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
819 : ContextHandler2( rParent )
820 , mrAdjPoint2D( rAdjPoint2D )
821 , mrCustomShapeProperties( rCustomShapeProperties )
825 ContextHandlerRef Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
827 if ( aElementToken == A_TOKEN( pt ) )
828 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
829 return nullptr;
832 // CT_Path2DLineTo
833 class Path2DLineToContext : public ContextHandler2
835 public:
836 Path2DLineToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
837 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
839 protected:
840 EnhancedCustomShapeParameterPair& mrAdjPoint2D;
841 CustomShapeProperties& mrCustomShapeProperties;
844 Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
845 : ContextHandler2( rParent )
846 , mrAdjPoint2D( rAdjPoint2D )
847 , mrCustomShapeProperties( rCustomShapeProperties )
851 ContextHandlerRef Path2DLineToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
853 if ( aElementToken == A_TOKEN( pt ) )
854 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
855 return nullptr;
858 // CT_Path2DQuadBezierTo
859 class Path2DQuadBezierToContext : public ContextHandler2
861 public:
862 Path2DQuadBezierToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rPt1, EnhancedCustomShapeParameterPair& rPt2 );
863 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
865 protected:
866 EnhancedCustomShapeParameterPair& mrPt1;
867 EnhancedCustomShapeParameterPair& mrPt2;
868 int nCount;
869 CustomShapeProperties& mrCustomShapeProperties;
872 Path2DQuadBezierToContext::Path2DQuadBezierToContext( ContextHandler2Helper const & rParent,
873 CustomShapeProperties& rCustomShapeProperties,
874 EnhancedCustomShapeParameterPair& rPt1,
875 EnhancedCustomShapeParameterPair& rPt2 )
876 : ContextHandler2( rParent )
877 , mrPt1( rPt1 )
878 , mrPt2( rPt2 )
879 , nCount( 0 )
880 , mrCustomShapeProperties( rCustomShapeProperties )
884 ContextHandlerRef Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
886 if ( aElementToken == A_TOKEN( pt ) )
887 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
888 return nullptr;
891 // CT_Path2DCubicBezierTo
892 class Path2DCubicBezierToContext : public ContextHandler2
894 public:
895 Path2DCubicBezierToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties,
896 EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair& );
897 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
899 protected:
900 CustomShapeProperties& mrCustomShapeProperties;
901 EnhancedCustomShapeParameterPair& mrControlPt1;
902 EnhancedCustomShapeParameterPair& mrControlPt2;
903 EnhancedCustomShapeParameterPair& mrEndPt;
904 int nCount;
907 Path2DCubicBezierToContext::Path2DCubicBezierToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties,
908 EnhancedCustomShapeParameterPair& rControlPt1,
909 EnhancedCustomShapeParameterPair& rControlPt2,
910 EnhancedCustomShapeParameterPair& rEndPt )
911 : ContextHandler2( rParent )
912 , mrCustomShapeProperties( rCustomShapeProperties )
913 , mrControlPt1( rControlPt1 )
914 , mrControlPt2( rControlPt2 )
915 , mrEndPt( rEndPt )
916 , nCount( 0 )
920 ContextHandlerRef Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
922 if ( aElementToken == A_TOKEN( pt ) )
923 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties,
924 nCount++ ? nCount == 2 ? mrControlPt2 : mrEndPt : mrControlPt1 ); // CT_AdjPoint2D
925 return nullptr;
928 // CT_Path2DContext
929 class Path2DContext : public ContextHandler2
931 public:
932 Path2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< css::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D );
933 virtual void onEndElement() override;
934 virtual ::oox::core::ContextHandlerRef
935 onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
937 protected:
938 Path2D& mrPath2D;
939 std::vector< css::drawing::EnhancedCustomShapeSegment >& mrSegments;
940 CustomShapeProperties& mrCustomShapeProperties;
943 Path2DContext::Path2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< css::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D )
944 : ContextHandler2( rParent )
945 , mrPath2D( rPath2D )
946 , mrSegments( rSegments )
947 , mrCustomShapeProperties( rCustomShapeProperties )
949 rPath2D.w = rAttribs.getString( XML_w, "" ).toInt64();
950 rPath2D.h = rAttribs.getString( XML_h, "" ).toInt64();
951 rPath2D.fill = rAttribs.getToken( XML_fill, XML_norm );
952 rPath2D.stroke = rAttribs.getBool( XML_stroke, true );
953 rPath2D.extrusionOk = rAttribs.getBool( XML_extrusionOk, true );
956 void Path2DContext::onEndElement()
958 EnhancedCustomShapeSegment aNewSegment;
959 switch ( mrPath2D.fill )
961 case XML_none:
962 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
963 break;
964 case XML_darken:
965 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKEN;
966 break;
967 case XML_darkenLess:
968 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKENLESS;
969 break;
970 case XML_lighten:
971 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTEN;
972 break;
973 case XML_lightenLess:
974 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
975 break;
977 if (mrPath2D.fill != XML_norm) {
978 aNewSegment.Count = 0;
979 mrSegments.push_back( aNewSegment );
981 if ( !mrPath2D.stroke )
983 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
984 aNewSegment.Count = 0;
985 mrSegments.push_back( aNewSegment );
987 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
988 aNewSegment.Count = 0;
989 mrSegments.push_back( aNewSegment );
993 ContextHandlerRef Path2DContext::onCreateContext( sal_Int32 aElementToken,
994 const AttributeList& rAttribs )
996 switch( aElementToken )
998 case A_TOKEN( close ) :
1000 // ignore close after move to (ppt does seems to do the same, see accentCallout2 preset for example)
1001 if ( mrSegments.empty() || ( mrSegments.back().Command != EnhancedCustomShapeSegmentCommand::MOVETO ) ) {
1002 EnhancedCustomShapeSegment aNewSegment;
1003 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
1004 aNewSegment.Count = 0;
1005 mrSegments.push_back( aNewSegment );
1008 break;
1009 case A_TOKEN( moveTo ) :
1011 EnhancedCustomShapeSegment aNewSegment;
1012 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
1013 aNewSegment.Count = 1;
1014 mrSegments.push_back( aNewSegment );
1016 EnhancedCustomShapeParameterPair aAdjPoint2D;
1017 mrPath2D.parameter.push_back( aAdjPoint2D );
1018 return new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1020 break;
1021 case A_TOKEN( lnTo ) :
1023 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
1024 mrSegments.back().Count++;
1025 else
1027 EnhancedCustomShapeSegment aSegment;
1028 aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
1029 aSegment.Count = 1;
1030 mrSegments.push_back( aSegment );
1032 EnhancedCustomShapeParameterPair aAdjPoint2D;
1033 mrPath2D.parameter.push_back( aAdjPoint2D );
1034 return new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1036 break;
1037 case A_TOKEN( arcTo ) : // CT_Path2DArcTo
1039 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCANGLETO ) )
1040 mrSegments.back().Count++;
1041 else
1043 EnhancedCustomShapeSegment aSegment;
1044 aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCANGLETO;
1045 aSegment.Count = 1;
1046 mrSegments.push_back( aSegment );
1049 EnhancedCustomShapeParameterPair aScale;
1050 EnhancedCustomShapeParameterPair aAngles;
1052 aScale.First = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_wR ).get() );
1053 aScale.Second = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_hR ).get() );
1055 CustomShapeGuide aGuide;
1056 sal_Int32 nArcNum = mrCustomShapeProperties.getArcNum();
1058 // start angle
1059 aGuide.maName = "arctosa" + OUString::number( nArcNum );
1060 aGuide.maFormula = "("
1061 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_stAng ).get() ) )
1062 + ")/60000.0";
1063 aAngles.First.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide );
1064 aAngles.First.Type = EnhancedCustomShapeParameterType::EQUATION;
1066 // swing angle
1067 aGuide.maName = "arctosw" + OUString::number( nArcNum );
1068 aGuide.maFormula = "("
1069 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_swAng ).get() ) )
1070 + ")/60000.0";
1071 aAngles.Second.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide );
1072 aAngles.Second.Type = EnhancedCustomShapeParameterType::EQUATION;
1074 mrPath2D.parameter.push_back( aScale );
1075 mrPath2D.parameter.push_back( aAngles );
1077 break;
1078 case A_TOKEN( quadBezTo ) :
1080 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
1081 mrSegments.back().Count++;
1082 else
1084 EnhancedCustomShapeSegment aSegment;
1085 aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
1086 aSegment.Count = 1;
1087 mrSegments.push_back( aSegment );
1089 EnhancedCustomShapeParameterPair aPt1;
1090 EnhancedCustomShapeParameterPair aPt2;
1091 mrPath2D.parameter.push_back( aPt1 );
1092 mrPath2D.parameter.push_back( aPt2 );
1093 return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties,
1094 mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1095 mrPath2D.parameter.back() );
1097 break;
1098 case A_TOKEN( cubicBezTo ) :
1100 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
1101 mrSegments.back().Count++;
1102 else
1104 EnhancedCustomShapeSegment aSegment;
1105 aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
1106 aSegment.Count = 1;
1107 mrSegments.push_back( aSegment );
1109 EnhancedCustomShapeParameterPair aControlPt1;
1110 EnhancedCustomShapeParameterPair aControlPt2;
1111 EnhancedCustomShapeParameterPair aEndPt;
1112 mrPath2D.parameter.push_back( aControlPt1 );
1113 mrPath2D.parameter.push_back( aControlPt2 );
1114 mrPath2D.parameter.push_back( aEndPt );
1115 return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties,
1116 mrPath2D.parameter[ mrPath2D.parameter.size() - 3 ],
1117 mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1118 mrPath2D.parameter.back() );
1120 break;
1122 return nullptr;
1125 // CT_Path2DList
1126 class Path2DListContext : public ContextHandler2
1128 public:
1129 Path2DListContext( ContextHandler2Helper const & rParent, CustomShapeProperties & rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1130 std::vector< Path2D >& rPath2DList );
1132 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
1134 protected:
1136 CustomShapeProperties& mrCustomShapeProperties;
1137 std::vector< css::drawing::EnhancedCustomShapeSegment >& mrSegments;
1138 std::vector< Path2D >& mrPath2DList;
1141 Path2DListContext:: Path2DListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1142 std::vector< Path2D >& rPath2DList )
1143 : ContextHandler2( rParent )
1144 , mrCustomShapeProperties( rCustomShapeProperties )
1145 , mrSegments( rSegments )
1146 , mrPath2DList( rPath2DList )
1150 ContextHandlerRef Path2DListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1152 if ( aElementToken == A_TOKEN( path ) )
1154 Path2D aPath2D;
1155 mrPath2DList.push_back( aPath2D );
1156 return new Path2DContext( *this, rAttribs, mrCustomShapeProperties, mrSegments, mrPath2DList.back() );
1158 return nullptr;
1161 // CT_CustomGeometry2D
1162 CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties )
1163 : ContextHandler2( rParent )
1164 , mrCustomShapeProperties( rCustomShapeProperties )
1168 ContextHandlerRef CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1170 switch( aElementToken )
1172 case A_TOKEN( avLst ): // CT_GeomGuideList adjust value list
1173 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1174 case A_TOKEN( gdLst ): // CT_GeomGuideList guide list
1175 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getGuideList() );
1176 case A_TOKEN( ahLst ): // CT_AdjustHandleList adjust handle list
1177 return new AdjustHandleListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustHandleList() );
1178 case A_TOKEN( cxnLst ): // CT_ConnectionSiteList connection site list
1179 return this;
1180 case A_TOKEN( rect ): // CT_GeomRectList geometry rect list
1182 GeomRect aGeomRect;
1183 aGeomRect.l = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_l ).get() );
1184 aGeomRect.t = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_t ).get() );
1185 aGeomRect.r = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_r ).get() );
1186 aGeomRect.b = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_b ).get() );
1187 mrCustomShapeProperties.getTextRect() = aGeomRect;
1189 break;
1190 case A_TOKEN( pathLst ): // CT_Path2DList 2d path list
1191 return new Path2DListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getSegments(), mrCustomShapeProperties.getPath2DList() );
1193 // from cxnLst:
1194 case A_TOKEN( cxn ): // CT_ConnectionSite
1196 ConnectionSite aConnectionSite;
1197 mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
1198 return new ConnectionSiteContext( *this, rAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
1201 return nullptr;
1204 // CT_PresetGeometry2D
1205 PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1206 : ContextHandler2( rParent )
1207 , mrCustomShapeProperties( rCustomShapeProperties )
1209 sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1210 OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1211 mrCustomShapeProperties.setShapePresetType( nShapeType );
1214 ContextHandlerRef PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1216 if ( aElementToken == A_TOKEN( avLst ) )
1217 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1218 else
1219 return this;
1222 // CT_PresetTextShape
1223 PresetTextShapeContext::PresetTextShapeContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1224 : ContextHandler2( rParent )
1225 , mrCustomShapeProperties( rCustomShapeProperties )
1227 sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1228 OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1229 mrCustomShapeProperties.setShapePresetType( nShapeType );
1232 ContextHandlerRef PresetTextShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1234 if ( aElementToken == A_TOKEN( avLst ) )
1235 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1236 else
1237 return this;
1242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */