Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / oox / source / drawingml / customshapegeometry.cxx
blob4f515fd2ab65987e4c26b26c5949294712622124
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 "oox/helper/helper.hxx"
28 #include "oox/helper/attributelist.hxx"
29 #include "oox/helper/propertymap.hxx"
30 #include <oox/token/namespaces.hxx>
31 #include <oox/token/tokens.hxx>
32 #include <unordered_map>
34 using namespace ::oox::core;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::drawing;
37 using namespace ::com::sun::star::xml::sax;
39 namespace oox { namespace drawingml {
41 enum FormularCommand
43 FC_MULDIV = 0,
44 FC_PLUSMINUS,
45 FC_PLUSDIV,
46 FC_IFELSE,
47 FC_IFELSE1,
48 FC_ABS,
49 FC_AT2,
50 FC_CAT2,
51 FC_COS,
52 FC_MAX,
53 FC_MIN,
54 FC_MOD,
55 FC_PIN,
56 FC_SAT2,
57 FC_SIN,
58 FC_SQRT,
59 FC_TAN,
60 FC_VAL
62 struct FormularCommandNameTable
64 const char* pS;
65 FormularCommand pE;
67 static const FormularCommandNameTable pFormularCommandNameTable[] =
69 { "*/", FC_MULDIV },
70 { "+-", FC_PLUSMINUS },
71 { "+/", FC_PLUSDIV },
72 { "ifelse", FC_IFELSE },
73 { "?:", FC_IFELSE1 },
74 { "abs", FC_ABS },
75 { "at2", FC_AT2 },
76 { "cat2", FC_CAT2 },
77 { "cos", FC_COS },
78 { "max", FC_MAX },
79 { "min", FC_MIN },
80 { "mod", FC_MOD },
81 { "pin", FC_PIN },
82 { "sat2", FC_SAT2 },
83 { "sin", FC_SIN },
84 { "sqrt", FC_SQRT },
85 { "tan", FC_TAN },
86 { "val", FC_VAL }
89 typedef std::unordered_map< OUString, FormularCommand, OUStringHash > FormulaCommandHMap;
91 static const FormulaCommandHMap* pCommandHashMap;
93 OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
95 OUString aRet;
96 switch( rParameter.Type )
98 case EnhancedCustomShapeParameterType::NORMAL :
100 if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
102 double fValue = 0.0;
103 if ( rParameter.Value >>= fValue )
104 aRet = OUString::number( fValue );
106 else
108 sal_Int32 nValue = 0;
109 if ( rParameter.Value >>= nValue )
110 aRet = OUString::number( nValue );
113 break;
114 case EnhancedCustomShapeParameterType::EQUATION :
116 if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
118 sal_Int32 nFormulaIndex;
119 if ( rParameter.Value >>= nFormulaIndex )
121 aRet = "?"
122 + OUString::number( nFormulaIndex )
123 + " ";
126 else
128 // ups... we should have an index here and not the formula name
131 break;
132 case EnhancedCustomShapeParameterType::ADJUSTMENT :
134 if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
136 sal_Int32 nAdjustmentIndex;
137 if ( rParameter.Value >>= nAdjustmentIndex )
139 aRet = "$"
140 + OUString::number( nAdjustmentIndex )
141 + " ";
144 else
146 // ups... we should have an index here and not the formula name
149 break;
150 case EnhancedCustomShapeParameterType::LEFT :
151 aRet = "left";
152 break;
153 case EnhancedCustomShapeParameterType::TOP :
154 aRet = "top";
155 break;
156 case EnhancedCustomShapeParameterType::RIGHT :
157 aRet = "right";
158 break;
159 case EnhancedCustomShapeParameterType::BOTTOM :
160 aRet = "bottom";
161 break;
162 case EnhancedCustomShapeParameterType::XSTRETCH :
163 aRet = "xstretch";
164 break;
165 case EnhancedCustomShapeParameterType::YSTRETCH :
166 aRet = "ystretch";
167 break;
168 case EnhancedCustomShapeParameterType::HASSTROKE :
169 aRet = "hasstroke";
170 break;
171 case EnhancedCustomShapeParameterType::HASFILL :
172 aRet = "hasfill";
173 break;
174 case EnhancedCustomShapeParameterType::WIDTH :
175 aRet = "width";
176 break;
177 case EnhancedCustomShapeParameterType::HEIGHT :
178 aRet = "height";
179 break;
180 case EnhancedCustomShapeParameterType::LOGWIDTH :
181 aRet = "logwidth";
182 break;
183 case EnhancedCustomShapeParameterType::LOGHEIGHT :
184 aRet = "logheight";
185 break;
187 return aRet;
190 static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const OUString& rValue, bool bNoSymbols = true )
192 css::drawing::EnhancedCustomShapeParameter aRet;
193 if ( !rValue.isEmpty() )
195 bool bConstant = true;
196 sal_Int32 nConstant = -1;
197 sal_Int32 nIntVal = 0;
199 // first check if it's a constant value
200 switch( AttributeConversion::decodeToken( rValue ) )
202 case XML_3cd4 : nConstant = 270 * 60000; break;
203 case XML_3cd8 : nConstant = 135 * 60000; break;
204 case XML_5cd8 : nConstant = 225 * 60000; break;
205 case XML_7cd8 : nConstant = 315 * 60000; break;
206 case XML_cd2 : nConstant = 180 * 60000; break;
207 case XML_cd3 : nConstant = 120 * 60000; break;
208 case XML_cd4 : nConstant = 90 * 60000; break;
209 case XML_cd8 : nConstant = 45 * 60000; break;
211 case XML_b : // variable height of the shape defined in spPr
212 case XML_h :
214 if ( bNoSymbols )
216 CustomShapeGuide aGuide;
217 aGuide.maName = rValue;
218 aGuide.maFormula = "logheight" ;
220 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
221 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
223 else
224 aRet.Type = EnhancedCustomShapeParameterType::LOGHEIGHT; // TODO: HEIGHT needs to be implemented
226 break;
228 case XML_hd10 :
229 nIntVal += 2; // */ h 1.0 10.0
230 SAL_FALLTHROUGH;
231 case XML_hd8 : // */ h 1.0 8.0
232 nIntVal += 2;
233 SAL_FALLTHROUGH;
234 case XML_hd6 : // */ h 1.0 6.0
235 nIntVal++;
236 SAL_FALLTHROUGH;
237 case XML_hd5 : // */ h 1.0 5.0
238 nIntVal++;
239 SAL_FALLTHROUGH;
240 case XML_hd4 : // */ h 1.0 4.0
241 nIntVal++;
242 SAL_FALLTHROUGH;
243 case XML_hd3 : // */ h 1.0 3.0
244 nIntVal++;
245 SAL_FALLTHROUGH;
246 case XML_hd2 : // */ h 1.0 2.0
247 case XML_vc : // */ h 1.0 2.0
249 nIntVal += 2;
251 CustomShapeGuide aGuide;
252 aGuide.maName = rValue;
253 aGuide.maFormula = "logheight/" + OUString::number( nIntVal );
255 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
256 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
258 break;
260 case XML_t :
261 case XML_l :
263 nConstant = 0;
264 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
266 break;
268 case XML_ls : // longest side: max w h
270 CustomShapeGuide aGuide;
271 aGuide.maName = rValue;
272 aGuide.maFormula = "max(logwidth,logheight)";
274 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
275 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
277 break;
278 case XML_ss : // shortest side: min w h
280 CustomShapeGuide aGuide;
281 aGuide.maName = rValue;
282 aGuide.maFormula = "min(logwidth,logheight)";
284 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
285 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
287 break;
288 case XML_ssd32 : // */ ss 1.0 32.0
289 nIntVal += 16;
290 SAL_FALLTHROUGH;
291 case XML_ssd16 : // */ ss 1.0 16.0
292 nIntVal += 8;
293 SAL_FALLTHROUGH;
294 case XML_ssd8 : // */ ss 1.0 8.0
295 nIntVal += 2;
296 SAL_FALLTHROUGH;
297 case XML_ssd6 : // */ ss 1.0 6.0
298 nIntVal += 2;
299 SAL_FALLTHROUGH;
300 case XML_ssd4 : // */ ss 1.0 4.0
301 nIntVal += 2;
302 SAL_FALLTHROUGH;
303 case XML_ssd2 : // */ ss 1.0 2.0
305 nIntVal += 2;
307 CustomShapeGuide aGuide;
308 aGuide.maName = rValue;
309 aGuide.maFormula = "min(logwidth,logheight)/" + OUString::number( nIntVal );
311 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
312 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
314 break;
316 case XML_r : // variable width of the shape defined in spPr
317 case XML_w :
319 if ( bNoSymbols )
321 CustomShapeGuide aGuide;
322 aGuide.maName = rValue;
323 aGuide.maFormula = "logwidth" ;
325 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
326 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
328 else
329 aRet.Type = EnhancedCustomShapeParameterType::LOGWIDTH;
331 break;
333 case XML_wd32 : // */ w 1.0 32.0
334 nIntVal += 20;
335 SAL_FALLTHROUGH;
336 case XML_wd12 : // */ w 1.0 12.0
337 nIntVal += 2;
338 SAL_FALLTHROUGH;
339 case XML_wd10 : // */ w 1.0 10.0
340 nIntVal += 2;
341 SAL_FALLTHROUGH;
342 case XML_wd8 : // */ w 1.0 8.0
343 nIntVal += 2;
344 SAL_FALLTHROUGH;
345 case XML_wd6 : // */ w 1.0 6.0
346 nIntVal++;
347 SAL_FALLTHROUGH;
348 case XML_wd5 : // */ w 1.0 5.0
349 nIntVal++;
350 SAL_FALLTHROUGH;
351 case XML_wd4 : // */ w 1.0 4.0
352 nIntVal++;
353 SAL_FALLTHROUGH;
354 case XML_wd3 : // */ w 1.0 3.0
355 nIntVal++;
356 SAL_FALLTHROUGH;
357 case XML_hc : // */ w 1.0 2.0
358 case XML_wd2 : // */ w 1.0 2.0
360 nIntVal += 2;
362 CustomShapeGuide aGuide;
363 aGuide.maName = rValue;
364 aGuide.maFormula = "logwidth/" + OUString::number( nIntVal );
366 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
367 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
369 break;
371 default:
372 bConstant = false;
373 break;
375 if ( bConstant )
377 if (nConstant != -1) {
378 aRet.Value <<= nConstant;
379 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
382 else
384 sal_Unicode n = rValue[ 0 ];
385 if ( ( n == '+' ) || ( n == '-' ) )
387 if ( rValue.getLength() > 1 )
388 n = rValue[ 1 ];
390 if ( ( n >= '0' ) && ( n <= '9' ) )
391 { // seems to be a ST_Coordinate
392 aRet.Value <<= rValue.toInt32();
393 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
395 else
397 sal_Int32 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getAdjustmentGuideList(), rValue );
398 if ( nGuideIndex >= 0 )
400 aRet.Value <<= nGuideIndex;
401 aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
403 else
405 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), rValue );
406 if ( nGuideIndex >= 0 )
408 aRet.Value <<= nGuideIndex;
409 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
411 else
413 SAL_WARN("oox", "error: unhandled value " << rValue);
414 aRet.Value <<= rValue;
420 return aRet;
423 // CT_GeomGuideList
424 class GeomGuideListContext : public ContextHandler2
426 public:
427 GeomGuideListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList );
428 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
430 protected:
431 std::vector< CustomShapeGuide >& mrGuideList;
432 CustomShapeProperties& mrCustomShapeProperties;
435 GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList )
436 : ContextHandler2( rParent )
437 , mrGuideList( rGuideList )
438 , mrCustomShapeProperties( rCustomShapeProperties )
442 static OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, const OUString& rSource )
444 if ( !pCommandHashMap )
446 FormulaCommandHMap* pHM = new FormulaCommandHMap;
447 for(const FormularCommandNameTable& i : pFormularCommandNameTable)
448 (*pHM)[ OUString::createFromAscii( i.pS ) ] = i.pE;
449 pCommandHashMap = pHM;
452 std::vector< OUString > aTokens;
453 sal_Int32 nIndex = 0;
456 OUString aToken( rSource.getToken( 0, ' ', nIndex ) );
457 if ( !aToken.isEmpty() )
458 aTokens.push_back( aToken );
460 while ( nIndex >= 0 );
462 OUString aEquation;
463 if ( !aTokens.empty() )
465 sal_Int32 i, nParameters = aTokens.size() - 1;
466 if ( nParameters > 3 )
467 nParameters = 3;
469 OUString sParameters[ 3 ];
471 for ( i = 0; i < nParameters; i++ )
472 sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], false ) );
474 const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
475 if ( aIter != pCommandHashMap->end() )
477 switch( aIter->second )
479 case FC_MULDIV :
481 if ( nParameters == 3 )
482 aEquation = sParameters[ 0 ] + "*" + sParameters[ 1 ]
483 + "/" + sParameters[ 2 ];
485 break;
486 case FC_PLUSMINUS :
488 if ( nParameters == 3 )
489 aEquation = sParameters[ 0 ] + "+" + sParameters[ 1 ]
490 + "-" + sParameters[ 2 ];
492 break;
493 case FC_PLUSDIV :
495 if ( nParameters == 3 )
496 aEquation = "(" + sParameters[ 0 ] + "+"
497 + sParameters[ 1 ] + ")/" + sParameters[ 2 ];
499 break;
500 case FC_IFELSE :
501 case FC_IFELSE1 :
503 if ( nParameters == 3 )
504 aEquation = "if(" + sParameters[ 0 ] + ","
505 + sParameters[ 1 ] + "," + sParameters[ 2 ] + ")";
507 break;
508 case FC_ABS :
510 if ( nParameters == 1 )
511 aEquation = "abs(" + sParameters[ 0 ] + ")";
513 break;
514 case FC_AT2 :
516 if ( nParameters == 2 )
517 aEquation = "(10800000*atan2(" + sParameters[ 1 ] + ","
518 + sParameters[ 0 ] + "))/pi";
520 break;
521 case FC_CAT2 :
523 if ( nParameters == 3 )
524 aEquation = sParameters[ 0 ] + "*(cos(atan2(" +
525 sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
527 break;
528 case FC_COS :
530 if ( nParameters == 2 )
531 aEquation = sParameters[ 0 ] + "*cos(pi*(" +
532 sParameters[ 1 ] + ")/10800000)";
534 break;
535 case FC_MAX :
537 if ( nParameters == 2 )
538 aEquation = "max(" + sParameters[ 0 ] + "," +
539 sParameters[ 1 ] + ")";
541 break;
542 case FC_MIN :
544 if ( nParameters == 2 )
545 aEquation = "min(" + sParameters[ 0 ] + "," +
546 sParameters[ 1 ] + ")";
548 break;
549 case FC_MOD :
551 if ( nParameters == 3 )
552 aEquation = "sqrt("
553 + sParameters[ 0 ] + "*" + sParameters[ 0 ] + "+"
554 + sParameters[ 1 ] + "*" + sParameters[ 1 ] + "+"
555 + sParameters[ 2 ] + "*" + sParameters[ 2 ] + ")";
557 break;
558 case FC_PIN :
560 if ( nParameters == 3 ) // if(x-y,x,if(y-z,z,y))
561 aEquation = "if(" + sParameters[ 0 ] + "-" + sParameters[ 1 ]
562 + "," + sParameters[ 0 ] + ",if(" + sParameters[ 2 ]
563 + "-" + sParameters[ 1 ] + "," + sParameters[ 1 ]
564 + "," + sParameters[ 2 ] + "))";
566 break;
567 case FC_SAT2 :
569 if ( nParameters == 3 )
570 aEquation = sParameters[ 0 ] + "*(sin(atan2(" +
571 sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
573 break;
574 case FC_SIN :
576 if ( nParameters == 2 )
577 aEquation = sParameters[ 0 ] + "*sin(pi*(" +
578 sParameters[ 1 ] + ")/10800000)";
580 break;
581 case FC_SQRT :
583 if ( nParameters == 1 )
584 aEquation = "sqrt(" + sParameters[ 0 ] + ")";
586 break;
587 case FC_TAN :
589 if ( nParameters == 2 )
590 aEquation = sParameters[ 0 ] + "*tan(pi*(" +
591 sParameters[ 1 ] + ")/10800000)";
593 break;
594 case FC_VAL :
596 if ( nParameters == 1 )
597 aEquation = sParameters[ 0 ];
599 break;
600 default :
601 break;
605 return aEquation;
608 ContextHandlerRef GeomGuideListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
610 if ( aElementToken == A_TOKEN( gd ) ) // CT_GeomGuide
612 CustomShapeGuide aGuide;
613 aGuide.maName = rAttribs.getString( XML_name ).get();
614 aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, rAttribs.getString( XML_fmla ).get() );
615 mrGuideList.push_back( aGuide );
617 return this;
620 static const OUString& GetGeomGuideName( const OUString& rValue )
622 return rValue;
625 // CT_AdjPoint2D
626 class AdjPoint2DContext : public ContextHandler2
628 public:
629 AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
632 AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
633 : ContextHandler2( rParent )
635 rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_x ).get() );
636 rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_y ).get() );
639 // CT_XYAdjustHandle
640 class XYAdjustHandleContext : public ContextHandler2
642 public:
643 XYAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
644 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
646 protected:
647 AdjustHandle& mrAdjustHandle;
648 CustomShapeProperties& mrCustomShapeProperties;
651 XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
652 : ContextHandler2( rParent )
653 , mrAdjustHandle( rAdjustHandle )
654 , mrCustomShapeProperties( rCustomShapeProperties )
656 if ( rAttribs.hasAttribute( XML_gdRefX ) )
658 mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefX, "" ) );
660 if ( rAttribs.hasAttribute( XML_minX ) )
662 mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minX, "" ) );
664 if ( rAttribs.hasAttribute( XML_maxX ) )
666 mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxX, "" ) );
668 if ( rAttribs.hasAttribute( XML_gdRefY ) )
670 mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefY, "" ) );
672 if ( rAttribs.hasAttribute( XML_minY ) )
674 mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minY, "" ) );
676 if ( rAttribs.hasAttribute( XML_maxY ) )
678 mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxY, "" ) );
682 ContextHandlerRef XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
684 if ( aElementToken == A_TOKEN( pos ) )
685 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
686 return nullptr;
689 // CT_PolarAdjustHandle
690 class PolarAdjustHandleContext : public ContextHandler2
692 public:
693 PolarAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
694 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
696 protected:
697 AdjustHandle& mrAdjustHandle;
698 CustomShapeProperties& mrCustomShapeProperties;
701 PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
702 : ContextHandler2( rParent )
703 , mrAdjustHandle( rAdjustHandle )
704 , mrCustomShapeProperties( rCustomShapeProperties )
706 if ( rAttribs.hasAttribute( XML_gdRefR ) )
708 mrAdjustHandle.polar = true ;
709 mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefR, "" ) );
711 if ( rAttribs.hasAttribute( XML_minR ) )
713 mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minR, "" ) );
715 if ( rAttribs.hasAttribute( XML_maxR ) )
717 mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxR, "" ) );
719 if ( rAttribs.hasAttribute( XML_gdRefAng ) )
721 mrAdjustHandle.polar = true ;
722 mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefAng, "" ) );
724 if ( rAttribs.hasAttribute( XML_minAng ) )
726 mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minAng, "" ) );
728 if ( rAttribs.hasAttribute( XML_maxAng ) )
730 mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxAng, "" ) );
734 ContextHandlerRef PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
736 // mrAdjustHandle.pos uses planar coordinates.
737 if ( aElementToken == A_TOKEN( pos ) )
738 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
739 return nullptr;
742 // CT_AdjustHandleList
743 class AdjustHandleListContext : public ContextHandler2
745 public:
746 AdjustHandleListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList );
747 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
749 protected:
750 std::vector< AdjustHandle >& mrAdjustHandleList;
751 CustomShapeProperties& mrCustomShapeProperties;
754 AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
755 : ContextHandler2( rParent )
756 , mrAdjustHandleList( rAdjustHandleList )
757 , mrCustomShapeProperties( rCustomShapeProperties )
761 ContextHandlerRef AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
763 if ( aElementToken == A_TOKEN( ahXY ) ) // CT_XYAdjustHandle
765 AdjustHandle aAdjustHandle( false );
766 mrAdjustHandleList.push_back( aAdjustHandle );
767 return new XYAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
769 else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
771 AdjustHandle aAdjustHandle( true );
772 mrAdjustHandleList.push_back( aAdjustHandle );
773 return new PolarAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
775 return nullptr;
778 // CT_ConnectionSite
779 class ConnectionSiteContext : public ContextHandler2
781 public:
782 ConnectionSiteContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite );
783 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
785 protected:
786 ConnectionSite& mrConnectionSite;
787 CustomShapeProperties& mrCustomShapeProperties;
790 ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
791 : ContextHandler2( rParent )
792 , mrConnectionSite( rConnectionSite )
793 , mrCustomShapeProperties( rCustomShapeProperties )
795 mrConnectionSite.ang = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_ang ).get() );
798 ContextHandlerRef ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
800 if ( aElementToken == A_TOKEN( pos ) )
801 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
802 return nullptr;
805 // CT_Path2DMoveTo
806 class Path2DMoveToContext : public ContextHandler2
808 public:
809 Path2DMoveToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
810 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
812 protected:
813 EnhancedCustomShapeParameterPair& mrAdjPoint2D;
814 CustomShapeProperties& mrCustomShapeProperties;
817 Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
818 : ContextHandler2( rParent )
819 , mrAdjPoint2D( rAdjPoint2D )
820 , mrCustomShapeProperties( rCustomShapeProperties )
824 ContextHandlerRef Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
826 if ( aElementToken == A_TOKEN( pt ) )
827 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
828 return nullptr;
831 // CT_Path2DLineTo
832 class Path2DLineToContext : public ContextHandler2
834 public:
835 Path2DLineToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
836 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
838 protected:
839 EnhancedCustomShapeParameterPair& mrAdjPoint2D;
840 CustomShapeProperties& mrCustomShapeProperties;
843 Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
844 : ContextHandler2( rParent )
845 , mrAdjPoint2D( rAdjPoint2D )
846 , mrCustomShapeProperties( rCustomShapeProperties )
850 ContextHandlerRef Path2DLineToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
852 if ( aElementToken == A_TOKEN( pt ) )
853 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
854 return nullptr;
857 // CT_Path2DQuadBezierTo
858 class Path2DQuadBezierToContext : public ContextHandler2
860 public:
861 Path2DQuadBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rPt1, EnhancedCustomShapeParameterPair& rPt2 );
862 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
864 protected:
865 EnhancedCustomShapeParameterPair& mrPt1;
866 EnhancedCustomShapeParameterPair& mrPt2;
867 int nCount;
868 CustomShapeProperties& mrCustomShapeProperties;
871 Path2DQuadBezierToContext::Path2DQuadBezierToContext( ContextHandler2Helper& rParent,
872 CustomShapeProperties& rCustomShapeProperties,
873 EnhancedCustomShapeParameterPair& rPt1,
874 EnhancedCustomShapeParameterPair& rPt2 )
875 : ContextHandler2( rParent )
876 , mrPt1( rPt1 )
877 , mrPt2( rPt2 )
878 , nCount( 0 )
879 , mrCustomShapeProperties( rCustomShapeProperties )
883 ContextHandlerRef Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
885 if ( aElementToken == A_TOKEN( pt ) )
886 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
887 return nullptr;
890 // CT_Path2DCubicBezierTo
891 class Path2DCubicBezierToContext : public ContextHandler2
893 public:
894 Path2DCubicBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties,
895 EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair& );
896 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
898 protected:
899 CustomShapeProperties& mrCustomShapeProperties;
900 EnhancedCustomShapeParameterPair& mrControlPt1;
901 EnhancedCustomShapeParameterPair& mrControlPt2;
902 EnhancedCustomShapeParameterPair& mrEndPt;
903 int nCount;
906 Path2DCubicBezierToContext::Path2DCubicBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties,
907 EnhancedCustomShapeParameterPair& rControlPt1,
908 EnhancedCustomShapeParameterPair& rControlPt2,
909 EnhancedCustomShapeParameterPair& rEndPt )
910 : ContextHandler2( rParent )
911 , mrCustomShapeProperties( rCustomShapeProperties )
912 , mrControlPt1( rControlPt1 )
913 , mrControlPt2( rControlPt2 )
914 , mrEndPt( rEndPt )
915 , nCount( 0 )
919 ContextHandlerRef Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
921 if ( aElementToken == A_TOKEN( pt ) )
922 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties,
923 nCount++ ? nCount == 2 ? mrControlPt2 : mrEndPt : mrControlPt1 ); // CT_AdjPoint2D
924 return nullptr;
927 // CT_Path2DContext
928 class Path2DContext : public ContextHandler2
930 public:
931 Path2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< css::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D );
932 virtual ~Path2DContext() override;
933 virtual ::oox::core::ContextHandlerRef
934 onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
936 protected:
937 Path2D& mrPath2D;
938 std::vector< css::drawing::EnhancedCustomShapeSegment >& mrSegments;
939 CustomShapeProperties& mrCustomShapeProperties;
942 Path2DContext::Path2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< css::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D )
943 : ContextHandler2( rParent )
944 , mrPath2D( rPath2D )
945 , mrSegments( rSegments )
946 , mrCustomShapeProperties( rCustomShapeProperties )
948 rPath2D.w = rAttribs.getString( XML_w, "" ).toInt64();
949 rPath2D.h = rAttribs.getString( XML_h, "" ).toInt64();
950 rPath2D.fill = rAttribs.getToken( XML_fill, XML_norm );
951 rPath2D.stroke = rAttribs.getBool( XML_stroke, true );
952 rPath2D.extrusionOk = rAttribs.getBool( XML_extrusionOk, true );
955 Path2DContext::~Path2DContext()
957 EnhancedCustomShapeSegment aNewSegment;
958 switch ( mrPath2D.fill )
960 case XML_none:
961 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
962 break;
963 case XML_darken:
964 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKEN;
965 break;
966 case XML_darkenLess:
967 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKENLESS;
968 break;
969 case XML_lighten:
970 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTEN;
971 break;
972 case XML_lightenLess:
973 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
974 break;
976 if (mrPath2D.fill != XML_norm) {
977 aNewSegment.Count = 0;
978 mrSegments.push_back( aNewSegment );
980 if ( !mrPath2D.stroke )
982 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
983 aNewSegment.Count = 0;
984 mrSegments.push_back( aNewSegment );
986 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
987 aNewSegment.Count = 0;
988 mrSegments.push_back( aNewSegment );
991 ContextHandlerRef Path2DContext::onCreateContext( sal_Int32 aElementToken,
992 const AttributeList& rAttribs )
994 switch( aElementToken )
996 case A_TOKEN( close ) :
998 // ignore close after move to (ppt does seems to do the same, see accentCallout2 preset for example)
999 if ( mrSegments.empty() || ( mrSegments.back().Command != EnhancedCustomShapeSegmentCommand::MOVETO ) ) {
1000 EnhancedCustomShapeSegment aNewSegment;
1001 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
1002 aNewSegment.Count = 0;
1003 mrSegments.push_back( aNewSegment );
1006 break;
1007 case A_TOKEN( moveTo ) :
1009 EnhancedCustomShapeSegment aNewSegment;
1010 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
1011 aNewSegment.Count = 1;
1012 mrSegments.push_back( aNewSegment );
1014 EnhancedCustomShapeParameterPair aAdjPoint2D;
1015 mrPath2D.parameter.push_back( aAdjPoint2D );
1016 return new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1018 break;
1019 case A_TOKEN( lnTo ) :
1021 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
1022 mrSegments.back().Count++;
1023 else
1025 EnhancedCustomShapeSegment aSegment;
1026 aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
1027 aSegment.Count = 1;
1028 mrSegments.push_back( aSegment );
1030 EnhancedCustomShapeParameterPair aAdjPoint2D;
1031 mrPath2D.parameter.push_back( aAdjPoint2D );
1032 return new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1034 break;
1035 case A_TOKEN( arcTo ) : // CT_Path2DArcTo
1037 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCANGLETO ) )
1038 mrSegments.back().Count++;
1039 else
1041 EnhancedCustomShapeSegment aSegment;
1042 aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCANGLETO;
1043 aSegment.Count = 1;
1044 mrSegments.push_back( aSegment );
1047 EnhancedCustomShapeParameterPair aScale;
1048 EnhancedCustomShapeParameterPair aAngles;
1050 aScale.First = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_wR ).get() );
1051 aScale.Second = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_hR ).get() );
1053 CustomShapeGuide aGuide;
1054 sal_Int32 nArcNum = mrCustomShapeProperties.getArcNum();
1056 // start angle
1057 aGuide.maName = "arctosa" + OUString::number( nArcNum );
1058 aGuide.maFormula = "("
1059 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_stAng ).get() ) )
1060 + ")/60000.0";
1061 aAngles.First.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide );
1062 aAngles.First.Type = EnhancedCustomShapeParameterType::EQUATION;
1064 // swing angle
1065 aGuide.maName = "arctosw" + OUString::number( nArcNum );
1066 aGuide.maFormula = "("
1067 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_swAng ).get() ) )
1068 + ")/60000.0";
1069 aAngles.Second.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide );
1070 aAngles.Second.Type = EnhancedCustomShapeParameterType::EQUATION;
1072 mrPath2D.parameter.push_back( aScale );
1073 mrPath2D.parameter.push_back( aAngles );
1075 break;
1076 case A_TOKEN( quadBezTo ) :
1078 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
1079 mrSegments.back().Count++;
1080 else
1082 EnhancedCustomShapeSegment aSegment;
1083 aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
1084 aSegment.Count = 1;
1085 mrSegments.push_back( aSegment );
1087 EnhancedCustomShapeParameterPair aPt1;
1088 EnhancedCustomShapeParameterPair aPt2;
1089 mrPath2D.parameter.push_back( aPt1 );
1090 mrPath2D.parameter.push_back( aPt2 );
1091 return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties,
1092 mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1093 mrPath2D.parameter.back() );
1095 break;
1096 case A_TOKEN( cubicBezTo ) :
1098 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
1099 mrSegments.back().Count++;
1100 else
1102 EnhancedCustomShapeSegment aSegment;
1103 aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
1104 aSegment.Count = 1;
1105 mrSegments.push_back( aSegment );
1107 EnhancedCustomShapeParameterPair aControlPt1;
1108 EnhancedCustomShapeParameterPair aControlPt2;
1109 EnhancedCustomShapeParameterPair aEndPt;
1110 mrPath2D.parameter.push_back( aControlPt1 );
1111 mrPath2D.parameter.push_back( aControlPt2 );
1112 mrPath2D.parameter.push_back( aEndPt );
1113 return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties,
1114 mrPath2D.parameter[ mrPath2D.parameter.size() - 3 ],
1115 mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1116 mrPath2D.parameter.back() );
1118 break;
1120 return nullptr;
1123 // CT_Path2DList
1124 class Path2DListContext : public ContextHandler2
1126 public:
1127 Path2DListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1128 std::vector< Path2D >& rPath2DList );
1130 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
1132 protected:
1134 CustomShapeProperties& mrCustomShapeProperties;
1135 std::vector< css::drawing::EnhancedCustomShapeSegment >& mrSegments;
1136 std::vector< Path2D >& mrPath2DList;
1139 Path2DListContext::Path2DListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1140 std::vector< Path2D >& rPath2DList )
1141 : ContextHandler2( rParent )
1142 , mrCustomShapeProperties( rCustomShapeProperties )
1143 , mrSegments( rSegments )
1144 , mrPath2DList( rPath2DList )
1148 ContextHandlerRef Path2DListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1150 if ( aElementToken == A_TOKEN( path ) )
1152 Path2D aPath2D;
1153 mrPath2DList.push_back( aPath2D );
1154 return new Path2DContext( *this, rAttribs, mrCustomShapeProperties, mrSegments, mrPath2DList.back() );
1156 return nullptr;
1159 // CT_CustomGeometry2D
1160 CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties )
1161 : ContextHandler2( rParent )
1162 , mrCustomShapeProperties( rCustomShapeProperties )
1166 ContextHandlerRef CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1168 switch( aElementToken )
1170 case A_TOKEN( avLst ): // CT_GeomGuideList adjust value list
1171 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1172 case A_TOKEN( gdLst ): // CT_GeomGuideList guide list
1173 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getGuideList() );
1174 case A_TOKEN( ahLst ): // CT_AdjustHandleList adjust handle list
1175 return new AdjustHandleListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustHandleList() );
1176 case A_TOKEN( cxnLst ): // CT_ConnectionSiteList connection site list
1177 return this;
1178 case A_TOKEN( rect ): // CT_GeomRectList geometry rect list
1180 GeomRect aGeomRect;
1181 aGeomRect.l = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_l ).get() );
1182 aGeomRect.t = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_t ).get() );
1183 aGeomRect.r = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_r ).get() );
1184 aGeomRect.b = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_b ).get() );
1185 mrCustomShapeProperties.getTextRect() = aGeomRect;
1187 break;
1188 case A_TOKEN( pathLst ): // CT_Path2DList 2d path list
1189 return new Path2DListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getSegments(), mrCustomShapeProperties.getPath2DList() );
1191 // from cxnLst:
1192 case A_TOKEN( cxn ): // CT_ConnectionSite
1194 ConnectionSite aConnectionSite;
1195 mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
1196 return new ConnectionSiteContext( *this, rAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
1199 return nullptr;
1202 // CT_PresetGeometry2D
1203 PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1204 : ContextHandler2( rParent )
1205 , mrCustomShapeProperties( rCustomShapeProperties )
1207 sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1208 OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1209 mrCustomShapeProperties.setShapePresetType( nShapeType );
1212 ContextHandlerRef PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1214 if ( aElementToken == A_TOKEN( avLst ) )
1215 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1216 else
1217 return this;
1220 // CT_PresetTextShape
1221 PresetTextShapeContext::PresetTextShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1222 : ContextHandler2( rParent )
1223 , mrCustomShapeProperties( rCustomShapeProperties )
1225 sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1226 OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1227 mrCustomShapeProperties.setShapePresetType( nShapeType );
1230 ContextHandlerRef PresetTextShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1232 if ( aElementToken == A_TOKEN( avLst ) )
1233 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1234 else
1235 return this;
1240 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */