tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / oox / source / drawingml / customshapegeometry.cxx
blobb029957959d82dec816cf1530247974253893f6b
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 <o3tl/string_view.hxx>
29 #include <oox/helper/helper.hxx>
30 #include <oox/helper/attributelist.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::drawingml {
42 namespace {
44 enum FormulaCommand
46 FC_MULDIV = 0,
47 FC_PLUSMINUS,
48 FC_PLUSDIV,
49 FC_IFELSE,
50 FC_IFELSE1,
51 FC_ABS,
52 FC_AT2,
53 FC_CAT2,
54 FC_COS,
55 FC_MAX,
56 FC_MIN,
57 FC_MOD,
58 FC_PIN,
59 FC_SAT2,
60 FC_SIN,
61 FC_SQRT,
62 FC_TAN,
63 FC_VAL
66 struct FormulaCommandNameTable
68 const char* pS;
69 FormulaCommand pE;
74 const FormulaCommandNameTable pFormulaCommandNameTable[] =
76 { "*/", FC_MULDIV },
77 { "+-", FC_PLUSMINUS },
78 { "+/", FC_PLUSDIV },
79 { "ifelse", FC_IFELSE },
80 { "?:", FC_IFELSE1 },
81 { "abs", FC_ABS },
82 { "at2", FC_AT2 },
83 { "cat2", FC_CAT2 },
84 { "cos", FC_COS },
85 { "max", FC_MAX },
86 { "min", FC_MIN },
87 { "mod", FC_MOD },
88 { "pin", FC_PIN },
89 { "sat2", FC_SAT2 },
90 { "sin", FC_SIN },
91 { "sqrt", FC_SQRT },
92 { "tan", FC_TAN },
93 { "val", FC_VAL }
96 typedef std::unordered_map< OUString, FormulaCommand > FormulaCommandHMap;
98 static const FormulaCommandHMap* pCommandHashMap;
100 static OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
102 OUString aRet;
103 switch( rParameter.Type )
105 case EnhancedCustomShapeParameterType::NORMAL :
107 if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
109 double fValue = 0.0;
110 if ( rParameter.Value >>= fValue )
111 aRet = OUString::number( fValue );
113 else
115 sal_Int32 nValue = 0;
116 if ( rParameter.Value >>= nValue )
117 aRet = OUString::number( nValue );
120 break;
121 case EnhancedCustomShapeParameterType::EQUATION :
123 if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
125 sal_Int32 nFormulaIndex;
126 if ( rParameter.Value >>= nFormulaIndex )
128 aRet = "?"
129 + OUString::number( nFormulaIndex )
130 + " ";
133 else
135 // ups... we should have an index here and not the formula name
138 break;
139 case EnhancedCustomShapeParameterType::ADJUSTMENT :
141 if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
143 sal_Int32 nAdjustmentIndex;
144 if ( rParameter.Value >>= nAdjustmentIndex )
146 aRet = "$"
147 + OUString::number( nAdjustmentIndex )
148 + " ";
151 else
153 // ups... we should have an index here and not the formula name
156 break;
157 case EnhancedCustomShapeParameterType::LEFT :
158 aRet = "left";
159 break;
160 case EnhancedCustomShapeParameterType::TOP :
161 aRet = "top";
162 break;
163 case EnhancedCustomShapeParameterType::RIGHT :
164 aRet = "right";
165 break;
166 case EnhancedCustomShapeParameterType::BOTTOM :
167 aRet = "bottom";
168 break;
169 case EnhancedCustomShapeParameterType::XSTRETCH :
170 aRet = "xstretch";
171 break;
172 case EnhancedCustomShapeParameterType::YSTRETCH :
173 aRet = "ystretch";
174 break;
175 case EnhancedCustomShapeParameterType::HASSTROKE :
176 aRet = "hasstroke";
177 break;
178 case EnhancedCustomShapeParameterType::HASFILL :
179 aRet = "hasfill";
180 break;
181 case EnhancedCustomShapeParameterType::WIDTH :
182 aRet = "width";
183 break;
184 case EnhancedCustomShapeParameterType::HEIGHT :
185 aRet = "height";
186 break;
187 case EnhancedCustomShapeParameterType::LOGWIDTH :
188 aRet = "logwidth";
189 break;
190 case EnhancedCustomShapeParameterType::LOGHEIGHT :
191 aRet = "logheight";
192 break;
194 return aRet;
197 static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const OUString& rValue, bool bNoSymbols = true )
199 css::drawing::EnhancedCustomShapeParameter aRet;
200 if ( !rValue.isEmpty() )
202 bool bConstant = true;
203 sal_Int32 nConstant = -1;
204 sal_Int32 nIntVal = 0;
206 // first check if it's a constant value
207 switch( AttributeConversion::decodeToken( rValue ) )
209 case XML_3cd4 : nConstant = 270 * 60000; break;
210 case XML_3cd8 : nConstant = 135 * 60000; break;
211 case XML_5cd8 : nConstant = 225 * 60000; break;
212 case XML_7cd8 : nConstant = 315 * 60000; break;
213 case XML_cd2 : nConstant = 180 * 60000; break;
214 case XML_cd3 : nConstant = 120 * 60000; break;
215 case XML_cd4 : nConstant = 90 * 60000; break;
216 case XML_cd8 : nConstant = 45 * 60000; break;
218 case XML_b : // variable height of the shape defined in spPr
219 case XML_h :
221 if ( bNoSymbols )
223 CustomShapeGuide aGuide;
224 aGuide.maName = rValue;
225 aGuide.maFormula = "logheight" ;
227 aRet.Value <<= rCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );
228 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
230 else
231 aRet.Type = EnhancedCustomShapeParameterType::LOGHEIGHT; // TODO: HEIGHT needs to be implemented
233 break;
235 case XML_hd10 :
236 nIntVal += 2; // */ h 1.0 10.0
237 [[fallthrough]];
238 case XML_hd8 : // */ h 1.0 8.0
239 nIntVal += 2;
240 [[fallthrough]];
241 case XML_hd6 : // */ h 1.0 6.0
242 nIntVal++;
243 [[fallthrough]];
244 case XML_hd5 : // */ h 1.0 5.0
245 nIntVal++;
246 [[fallthrough]];
247 case XML_hd4 : // */ h 1.0 4.0
248 nIntVal++;
249 [[fallthrough]];
250 case XML_hd3 : // */ h 1.0 3.0
251 nIntVal++;
252 [[fallthrough]];
253 case XML_hd2 : // */ h 1.0 2.0
254 case XML_vc : // */ h 1.0 2.0
256 nIntVal += 2;
258 CustomShapeGuide aGuide;
259 aGuide.maName = rValue;
260 aGuide.maFormula = "logheight/" + OUString::number( nIntVal );
262 aRet.Value <<= rCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );
263 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
265 break;
267 case XML_t :
268 case XML_l :
270 nConstant = 0;
271 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
273 break;
275 case XML_ls : // longest side: max w h
277 CustomShapeGuide aGuide;
278 aGuide.maName = rValue;
279 aGuide.maFormula = "max(logwidth,logheight)";
281 aRet.Value <<= rCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );
282 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
284 break;
285 case XML_ss : // shortest side: min w h
287 CustomShapeGuide aGuide;
288 aGuide.maName = rValue;
289 aGuide.maFormula = "min(logwidth,logheight)";
291 aRet.Value <<= rCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );
292 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
294 break;
295 case XML_ssd32 : // */ ss 1.0 32.0
296 nIntVal += 16;
297 [[fallthrough]];
298 case XML_ssd16 : // */ ss 1.0 16.0
299 nIntVal += 8;
300 [[fallthrough]];
301 case XML_ssd8 : // */ ss 1.0 8.0
302 nIntVal += 2;
303 [[fallthrough]];
304 case XML_ssd6 : // */ ss 1.0 6.0
305 nIntVal += 2;
306 [[fallthrough]];
307 case XML_ssd4 : // */ ss 1.0 4.0
308 nIntVal += 2;
309 [[fallthrough]];
310 case XML_ssd2 : // */ ss 1.0 2.0
312 nIntVal += 2;
314 CustomShapeGuide aGuide;
315 aGuide.maName = rValue;
316 aGuide.maFormula = "min(logwidth,logheight)/" + OUString::number( nIntVal );
318 aRet.Value <<= rCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );
319 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
321 break;
323 case XML_r : // variable width of the shape defined in spPr
324 case XML_w :
326 if ( bNoSymbols )
328 CustomShapeGuide aGuide;
329 aGuide.maName = rValue;
330 aGuide.maFormula = "logwidth" ;
332 aRet.Value <<= rCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );
333 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
335 else
336 aRet.Type = EnhancedCustomShapeParameterType::LOGWIDTH;
338 break;
340 case XML_wd32 : // */ w 1.0 32.0
341 nIntVal += 20;
342 [[fallthrough]];
343 case XML_wd12 : // */ w 1.0 12.0
344 nIntVal += 2;
345 [[fallthrough]];
346 case XML_wd10 : // */ w 1.0 10.0
347 nIntVal += 2;
348 [[fallthrough]];
349 case XML_wd8 : // */ w 1.0 8.0
350 nIntVal += 2;
351 [[fallthrough]];
352 case XML_wd6 : // */ w 1.0 6.0
353 nIntVal++;
354 [[fallthrough]];
355 case XML_wd5 : // */ w 1.0 5.0
356 nIntVal++;
357 [[fallthrough]];
358 case XML_wd4 : // */ w 1.0 4.0
359 nIntVal++;
360 [[fallthrough]];
361 case XML_wd3 : // */ w 1.0 3.0
362 nIntVal++;
363 [[fallthrough]];
364 case XML_hc : // */ w 1.0 2.0
365 case XML_wd2 : // */ w 1.0 2.0
367 nIntVal += 2;
369 CustomShapeGuide aGuide;
370 aGuide.maName = rValue;
371 aGuide.maFormula = "logwidth/" + OUString::number( nIntVal );
373 aRet.Value <<= rCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );;
374 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
376 break;
378 default:
379 bConstant = false;
380 break;
382 if ( bConstant )
384 if (nConstant != -1) {
385 aRet.Value <<= nConstant;
386 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
389 else
391 sal_Unicode n = rValue[ 0 ];
392 if ( ( n == '+' ) || ( n == '-' ) )
394 if ( rValue.getLength() > 1 )
395 n = rValue[ 1 ];
397 if ( ( n >= '0' ) && ( n <= '9' ) )
398 { // seems to be a ST_Coordinate
399 aRet.Value <<= rValue.toInt32();
400 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
402 else
404 sal_Int32 nGuideIndex = rCustomShapeProperties.getAdjustmentGuideList().GetCustomShapeGuideValue( rValue );
405 if ( nGuideIndex >= 0 )
407 aRet.Value <<= nGuideIndex;
408 aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
410 else
412 nGuideIndex = rCustomShapeProperties.getGuideList().GetCustomShapeGuideValue( rValue );
413 if ( nGuideIndex >= 0 )
415 aRet.Value <<= nGuideIndex;
416 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
418 else
420 SAL_WARN("oox", "error: unhandled value " << rValue);
421 aRet.Value <<= rValue;
427 return aRet;
430 namespace {
432 // CT_GeomGuideList
433 class GeomGuideListContext : public ContextHandler2
435 public:
436 GeomGuideListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, CustomShapeGuideContainer& rGuideList );
437 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
439 protected:
440 CustomShapeGuideContainer& mrGuideList;
441 CustomShapeProperties& mrCustomShapeProperties;
446 GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, CustomShapeGuideContainer& rGuideList )
447 : ContextHandler2( rParent )
448 , mrGuideList( rGuideList )
449 , mrCustomShapeProperties( rCustomShapeProperties )
453 static OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, std::u16string_view rSource )
455 if ( !pCommandHashMap )
457 FormulaCommandHMap* pHM = new FormulaCommandHMap;
458 for(const FormulaCommandNameTable& i : pFormulaCommandNameTable)
459 (*pHM)[ OUString::createFromAscii( i.pS ) ] = i.pE;
460 pCommandHashMap = pHM;
463 std::vector< OUString > aTokens;
464 sal_Int32 nIndex = 0;
467 OUString aToken( o3tl::getToken(rSource, 0, ' ', nIndex ) );
468 if ( !aToken.isEmpty() )
469 aTokens.push_back( aToken );
471 while ( nIndex >= 0 );
473 OUString aEquation;
474 if ( !aTokens.empty() )
476 sal_Int32 i, nParameters = aTokens.size() - 1;
477 if ( nParameters > 3 )
478 nParameters = 3;
480 OUString sParameters[ 3 ];
482 for ( i = 0; i < nParameters; i++ )
483 sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], false ) );
485 const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
486 if ( aIter != pCommandHashMap->end() )
488 switch( aIter->second )
490 case FC_MULDIV :
492 if ( nParameters == 3 )
493 aEquation = sParameters[ 0 ] + "*" + sParameters[ 1 ]
494 + "/" + sParameters[ 2 ];
496 break;
497 case FC_PLUSMINUS :
499 if ( nParameters == 3 )
500 aEquation = sParameters[ 0 ] + "+" + sParameters[ 1 ]
501 + "-" + sParameters[ 2 ];
503 break;
504 case FC_PLUSDIV :
506 if ( nParameters == 3 )
507 aEquation = "(" + sParameters[ 0 ] + "+"
508 + sParameters[ 1 ] + ")/" + sParameters[ 2 ];
510 break;
511 case FC_IFELSE :
512 case FC_IFELSE1 :
514 if ( nParameters == 3 )
515 aEquation = "if(" + sParameters[ 0 ] + ","
516 + sParameters[ 1 ] + "," + sParameters[ 2 ] + ")";
518 break;
519 case FC_ABS :
521 if ( nParameters == 1 )
522 aEquation = "abs(" + sParameters[ 0 ] + ")";
524 break;
525 case FC_AT2 :
527 if ( nParameters == 2 )
528 aEquation = "(10800000*atan2(" + sParameters[ 1 ] + ","
529 + sParameters[ 0 ] + "))/pi";
531 break;
532 case FC_CAT2 :
534 if ( nParameters == 3 )
535 aEquation = sParameters[ 0 ] + "*(cos(atan2(" +
536 sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
538 break;
539 case FC_COS :
541 if ( nParameters == 2 )
542 aEquation = sParameters[ 0 ] + "*cos(pi*(" +
543 sParameters[ 1 ] + ")/10800000)";
545 break;
546 case FC_MAX :
548 if ( nParameters == 2 )
549 aEquation = "max(" + sParameters[ 0 ] + "," +
550 sParameters[ 1 ] + ")";
552 break;
553 case FC_MIN :
555 if ( nParameters == 2 )
556 aEquation = "min(" + sParameters[ 0 ] + "," +
557 sParameters[ 1 ] + ")";
559 break;
560 case FC_MOD :
562 if ( nParameters == 3 )
563 aEquation = "sqrt("
564 + sParameters[ 0 ] + "*" + sParameters[ 0 ] + "+"
565 + sParameters[ 1 ] + "*" + sParameters[ 1 ] + "+"
566 + sParameters[ 2 ] + "*" + sParameters[ 2 ] + ")";
568 break;
569 case FC_PIN :
571 if ( nParameters == 3 ) // if(x-y,x,if(y-z,z,y))
572 aEquation = "if(" + sParameters[ 0 ] + "-" + sParameters[ 1 ]
573 + "," + sParameters[ 0 ] + ",if(" + sParameters[ 2 ]
574 + "-" + sParameters[ 1 ] + "," + sParameters[ 1 ]
575 + "," + sParameters[ 2 ] + "))";
577 break;
578 case FC_SAT2 :
580 if ( nParameters == 3 )
581 aEquation = sParameters[ 0 ] + "*(sin(atan2(" +
582 sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
584 break;
585 case FC_SIN :
587 if ( nParameters == 2 )
588 aEquation = sParameters[ 0 ] + "*sin(pi*(" +
589 sParameters[ 1 ] + ")/10800000)";
591 break;
592 case FC_SQRT :
594 if ( nParameters == 1 )
595 aEquation = "sqrt(" + sParameters[ 0 ] + ")";
597 break;
598 case FC_TAN :
600 if ( nParameters == 2 )
601 aEquation = sParameters[ 0 ] + "*tan(pi*(" +
602 sParameters[ 1 ] + ")/10800000)";
604 break;
605 case FC_VAL :
607 if ( nParameters == 1 )
608 aEquation = sParameters[ 0 ];
610 break;
611 default :
612 break;
616 return aEquation;
619 ContextHandlerRef GeomGuideListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
621 if ( aElementToken == A_TOKEN( gd ) ) // CT_GeomGuide
623 CustomShapeGuide aGuide;
624 aGuide.maName = rAttribs.getStringDefaulted( XML_name );
625 aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_fmla ) );
626 mrGuideList.push_back( aGuide );
628 return this;
631 static const OUString& GetGeomGuideName( const OUString& rValue )
633 return rValue;
636 namespace {
638 // CT_AdjPoint2D
639 class AdjPoint2DContext : public ContextHandler2
641 public:
642 AdjPoint2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
647 AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
648 : ContextHandler2( rParent )
650 rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getStringDefaulted( XML_x ) );
651 rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getStringDefaulted( XML_y ) );
654 namespace {
656 // CT_XYAdjustHandle
657 class XYAdjustHandleContext : public ContextHandler2
659 public:
660 XYAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
661 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
663 protected:
664 AdjustHandle& mrAdjustHandle;
665 CustomShapeProperties& mrCustomShapeProperties;
670 XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
671 : ContextHandler2( rParent )
672 , mrAdjustHandle( rAdjustHandle )
673 , mrCustomShapeProperties( rCustomShapeProperties )
675 if ( rAttribs.hasAttribute( XML_gdRefX ) )
677 mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getStringDefaulted( XML_gdRefX) );
679 if ( rAttribs.hasAttribute( XML_minX ) )
681 mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_minX) );
683 if ( rAttribs.hasAttribute( XML_maxX ) )
685 mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_maxX) );
687 if ( rAttribs.hasAttribute( XML_gdRefY ) )
689 mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getStringDefaulted( XML_gdRefY) );
691 if ( rAttribs.hasAttribute( XML_minY ) )
693 mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_minY) );
695 if ( rAttribs.hasAttribute( XML_maxY ) )
697 mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_maxY) );
701 ContextHandlerRef XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
703 if ( aElementToken == A_TOKEN( pos ) )
704 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
705 return nullptr;
708 namespace {
710 // CT_PolarAdjustHandle
711 class PolarAdjustHandleContext : public ContextHandler2
713 public:
714 PolarAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
715 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
717 protected:
718 AdjustHandle& mrAdjustHandle;
719 CustomShapeProperties& mrCustomShapeProperties;
724 PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
725 : ContextHandler2( rParent )
726 , mrAdjustHandle( rAdjustHandle )
727 , mrCustomShapeProperties( rCustomShapeProperties )
729 if ( rAttribs.hasAttribute( XML_gdRefR ) )
731 mrAdjustHandle.polar = true ;
732 mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getStringDefaulted( XML_gdRefR) );
734 if ( rAttribs.hasAttribute( XML_minR ) )
736 mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_minR) );
738 if ( rAttribs.hasAttribute( XML_maxR ) )
740 mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_maxR) );
742 if ( rAttribs.hasAttribute( XML_gdRefAng ) )
744 mrAdjustHandle.polar = true ;
745 mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getStringDefaulted( XML_gdRefAng) );
747 if ( rAttribs.hasAttribute( XML_minAng ) )
749 mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_minAng) );
751 if ( rAttribs.hasAttribute( XML_maxAng ) )
753 mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_maxAng) );
757 ContextHandlerRef PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
759 // mrAdjustHandle.pos uses planar coordinates.
760 if ( aElementToken == A_TOKEN( pos ) )
761 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
762 return nullptr;
765 namespace {
767 // CT_AdjustHandleList
768 class AdjustHandleListContext : public ContextHandler2
770 public:
771 AdjustHandleListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList );
772 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
774 protected:
775 std::vector< AdjustHandle >& mrAdjustHandleList;
776 CustomShapeProperties& mrCustomShapeProperties;
781 AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
782 : ContextHandler2( rParent )
783 , mrAdjustHandleList( rAdjustHandleList )
784 , mrCustomShapeProperties( rCustomShapeProperties )
788 ContextHandlerRef AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
790 if ( aElementToken == A_TOKEN( ahXY ) ) // CT_XYAdjustHandle
792 AdjustHandle aAdjustHandle( false );
793 mrAdjustHandleList.push_back( aAdjustHandle );
794 return new XYAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
796 else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
798 AdjustHandle aAdjustHandle( true );
799 mrAdjustHandleList.push_back( aAdjustHandle );
800 return new PolarAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
802 return nullptr;
805 namespace {
807 // CT_ConnectionSite
808 class ConnectionSiteContext : public ContextHandler2
810 public:
811 ConnectionSiteContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite );
812 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
814 protected:
815 ConnectionSite& mrConnectionSite;
816 CustomShapeProperties& mrCustomShapeProperties;
821 ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
822 : ContextHandler2( rParent )
823 , mrConnectionSite( rConnectionSite )
824 , mrCustomShapeProperties( rCustomShapeProperties )
826 mrConnectionSite.ang = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_ang ) );
829 ContextHandlerRef ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
831 if ( aElementToken == A_TOKEN( pos ) )
832 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
833 return nullptr;
836 namespace {
838 // CT_Path2DMoveTo
839 class Path2DMoveToContext : public ContextHandler2
841 public:
842 Path2DMoveToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
843 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
845 protected:
846 EnhancedCustomShapeParameterPair& mrAdjPoint2D;
847 CustomShapeProperties& mrCustomShapeProperties;
852 Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
853 : ContextHandler2( rParent )
854 , mrAdjPoint2D( rAdjPoint2D )
855 , mrCustomShapeProperties( rCustomShapeProperties )
859 ContextHandlerRef Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
861 if ( aElementToken == A_TOKEN( pt ) )
862 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
863 return nullptr;
866 namespace {
868 // CT_Path2DLineTo
869 class Path2DLineToContext : public ContextHandler2
871 public:
872 Path2DLineToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
873 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
875 protected:
876 EnhancedCustomShapeParameterPair& mrAdjPoint2D;
877 CustomShapeProperties& mrCustomShapeProperties;
882 Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
883 : ContextHandler2( rParent )
884 , mrAdjPoint2D( rAdjPoint2D )
885 , mrCustomShapeProperties( rCustomShapeProperties )
889 ContextHandlerRef Path2DLineToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
891 if ( aElementToken == A_TOKEN( pt ) )
892 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
893 return nullptr;
896 namespace {
898 // CT_Path2DQuadBezierTo
899 class Path2DQuadBezierToContext : public ContextHandler2
901 public:
902 Path2DQuadBezierToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rPt1, EnhancedCustomShapeParameterPair& rPt2 );
903 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
905 protected:
906 EnhancedCustomShapeParameterPair& mrPt1;
907 EnhancedCustomShapeParameterPair& mrPt2;
908 int nCount;
909 CustomShapeProperties& mrCustomShapeProperties;
914 Path2DQuadBezierToContext::Path2DQuadBezierToContext( ContextHandler2Helper const & rParent,
915 CustomShapeProperties& rCustomShapeProperties,
916 EnhancedCustomShapeParameterPair& rPt1,
917 EnhancedCustomShapeParameterPair& rPt2 )
918 : ContextHandler2( rParent )
919 , mrPt1( rPt1 )
920 , mrPt2( rPt2 )
921 , nCount( 0 )
922 , mrCustomShapeProperties( rCustomShapeProperties )
926 ContextHandlerRef Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
928 if ( aElementToken == A_TOKEN( pt ) )
929 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
930 return nullptr;
933 namespace {
935 // CT_Path2DCubicBezierTo
936 class Path2DCubicBezierToContext : public ContextHandler2
938 public:
939 Path2DCubicBezierToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties,
940 EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair& );
941 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
943 protected:
944 CustomShapeProperties& mrCustomShapeProperties;
945 EnhancedCustomShapeParameterPair& mrControlPt1;
946 EnhancedCustomShapeParameterPair& mrControlPt2;
947 EnhancedCustomShapeParameterPair& mrEndPt;
948 int nCount;
953 Path2DCubicBezierToContext::Path2DCubicBezierToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties,
954 EnhancedCustomShapeParameterPair& rControlPt1,
955 EnhancedCustomShapeParameterPair& rControlPt2,
956 EnhancedCustomShapeParameterPair& rEndPt )
957 : ContextHandler2( rParent )
958 , mrCustomShapeProperties( rCustomShapeProperties )
959 , mrControlPt1( rControlPt1 )
960 , mrControlPt2( rControlPt2 )
961 , mrEndPt( rEndPt )
962 , nCount( 0 )
966 ContextHandlerRef Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
968 if ( aElementToken == A_TOKEN( pt ) )
969 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties,
970 nCount++ ? nCount == 2 ? mrControlPt2 : mrEndPt : mrControlPt1 ); // CT_AdjPoint2D
971 return nullptr;
974 namespace {
976 // CT_Path2DContext
977 class Path2DContext : public ContextHandler2
979 public:
980 Path2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< css::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D );
981 virtual void onEndElement() override;
982 virtual ::oox::core::ContextHandlerRef
983 onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
985 protected:
986 Path2D& mrPath2D;
987 std::vector< css::drawing::EnhancedCustomShapeSegment >& mrSegments;
988 CustomShapeProperties& mrCustomShapeProperties;
993 Path2DContext::Path2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< css::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D )
994 : ContextHandler2( rParent )
995 , mrPath2D( rPath2D )
996 , mrSegments( rSegments )
997 , mrCustomShapeProperties( rCustomShapeProperties )
999 rPath2D.w = rAttribs.getHyper( XML_w, 0 );
1000 rPath2D.h = rAttribs.getHyper( XML_h, 0 );
1001 rPath2D.fill = rAttribs.getToken( XML_fill, XML_norm );
1002 rPath2D.stroke = rAttribs.getBool( XML_stroke, true );
1003 rPath2D.extrusionOk = rAttribs.getBool( XML_extrusionOk, true );
1006 void Path2DContext::onEndElement()
1008 EnhancedCustomShapeSegment aNewSegment;
1009 switch ( mrPath2D.fill )
1011 case XML_none:
1012 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
1013 break;
1014 case XML_darken:
1015 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKEN;
1016 break;
1017 case XML_darkenLess:
1018 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKENLESS;
1019 break;
1020 case XML_lighten:
1021 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTEN;
1022 break;
1023 case XML_lightenLess:
1024 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
1025 break;
1027 if (mrPath2D.fill != XML_norm) {
1028 aNewSegment.Count = 0;
1029 mrSegments.push_back( aNewSegment );
1031 if ( !mrPath2D.stroke )
1033 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
1034 aNewSegment.Count = 0;
1035 mrSegments.push_back( aNewSegment );
1037 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
1038 aNewSegment.Count = 0;
1039 mrSegments.push_back( aNewSegment );
1043 ContextHandlerRef Path2DContext::onCreateContext( sal_Int32 aElementToken,
1044 const AttributeList& rAttribs )
1046 switch( aElementToken )
1048 case A_TOKEN( close ) :
1050 // ignore close after move to (ppt does seems to do the same, see accentCallout2 preset for example)
1051 if ( mrSegments.empty() || ( mrSegments.back().Command != EnhancedCustomShapeSegmentCommand::MOVETO ) ) {
1052 EnhancedCustomShapeSegment aNewSegment;
1053 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
1054 aNewSegment.Count = 0;
1055 mrSegments.push_back( aNewSegment );
1058 break;
1059 case A_TOKEN( moveTo ) :
1061 EnhancedCustomShapeSegment aNewSegment;
1062 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
1063 aNewSegment.Count = 1;
1064 mrSegments.push_back( aNewSegment );
1066 EnhancedCustomShapeParameterPair aAdjPoint2D;
1067 mrPath2D.parameter.push_back( aAdjPoint2D );
1068 return new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1070 break;
1071 case A_TOKEN( lnTo ) :
1073 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
1074 mrSegments.back().Count++;
1075 else
1077 EnhancedCustomShapeSegment aSegment;
1078 aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
1079 aSegment.Count = 1;
1080 mrSegments.push_back( aSegment );
1082 EnhancedCustomShapeParameterPair aAdjPoint2D;
1083 mrPath2D.parameter.push_back( aAdjPoint2D );
1084 return new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1086 break;
1087 case A_TOKEN( arcTo ) : // CT_Path2DArcTo
1089 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCANGLETO ) )
1090 mrSegments.back().Count++;
1091 else
1093 EnhancedCustomShapeSegment aSegment;
1094 aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCANGLETO;
1095 aSegment.Count = 1;
1096 mrSegments.push_back( aSegment );
1099 EnhancedCustomShapeParameterPair aScale;
1100 EnhancedCustomShapeParameterPair aAngles;
1102 aScale.First = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_wR ) );
1103 aScale.Second = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_hR ) );
1105 CustomShapeGuide aGuide;
1106 sal_Int32 nArcNum = mrCustomShapeProperties.getArcNum();
1108 // start angle
1109 aGuide.maName = "arctosa" + OUString::number( nArcNum );
1110 aGuide.maFormula = "("
1111 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_stAng ) ) )
1112 + ")/60000.0";
1113 aAngles.First.Value <<= mrCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );
1114 aAngles.First.Type = EnhancedCustomShapeParameterType::EQUATION;
1116 // swing angle
1117 aGuide.maName = "arctosw" + OUString::number( nArcNum );
1118 aGuide.maFormula = "("
1119 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_swAng ) ) )
1120 + ")/60000.0";
1121 aAngles.Second.Value <<= mrCustomShapeProperties.getGuideList().SetCustomShapeGuideValue( aGuide );
1122 aAngles.Second.Type = EnhancedCustomShapeParameterType::EQUATION;
1124 mrPath2D.parameter.push_back( aScale );
1125 mrPath2D.parameter.push_back( aAngles );
1127 break;
1128 case A_TOKEN( quadBezTo ) :
1130 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
1131 mrSegments.back().Count++;
1132 else
1134 EnhancedCustomShapeSegment aSegment;
1135 aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
1136 aSegment.Count = 1;
1137 mrSegments.push_back( aSegment );
1139 EnhancedCustomShapeParameterPair aPt1;
1140 EnhancedCustomShapeParameterPair aPt2;
1141 mrPath2D.parameter.push_back( aPt1 );
1142 mrPath2D.parameter.push_back( aPt2 );
1143 return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties,
1144 mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1145 mrPath2D.parameter.back() );
1147 break;
1148 case A_TOKEN( cubicBezTo ) :
1150 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
1151 mrSegments.back().Count++;
1152 else
1154 EnhancedCustomShapeSegment aSegment;
1155 aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
1156 aSegment.Count = 1;
1157 mrSegments.push_back( aSegment );
1159 EnhancedCustomShapeParameterPair aControlPt1;
1160 EnhancedCustomShapeParameterPair aControlPt2;
1161 EnhancedCustomShapeParameterPair aEndPt;
1162 mrPath2D.parameter.push_back( aControlPt1 );
1163 mrPath2D.parameter.push_back( aControlPt2 );
1164 mrPath2D.parameter.push_back( aEndPt );
1165 return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties,
1166 mrPath2D.parameter[ mrPath2D.parameter.size() - 3 ],
1167 mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1168 mrPath2D.parameter.back() );
1170 break;
1172 return nullptr;
1175 namespace {
1177 // CT_Path2DList
1178 class Path2DListContext : public ContextHandler2
1180 public:
1181 Path2DListContext( ContextHandler2Helper const & rParent, CustomShapeProperties & rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1182 std::vector< Path2D >& rPath2DList );
1184 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
1186 protected:
1188 CustomShapeProperties& mrCustomShapeProperties;
1189 std::vector< css::drawing::EnhancedCustomShapeSegment >& mrSegments;
1190 std::vector< Path2D >& mrPath2DList;
1195 Path2DListContext:: Path2DListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1196 std::vector< Path2D >& rPath2DList )
1197 : ContextHandler2( rParent )
1198 , mrCustomShapeProperties( rCustomShapeProperties )
1199 , mrSegments( rSegments )
1200 , mrPath2DList( rPath2DList )
1204 ContextHandlerRef Path2DListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1206 if ( aElementToken == A_TOKEN( path ) )
1208 Path2D aPath2D;
1209 mrPath2DList.push_back( aPath2D );
1210 return new Path2DContext( *this, rAttribs, mrCustomShapeProperties, mrSegments, mrPath2DList.back() );
1212 return nullptr;
1215 // CT_CustomGeometry2D
1216 CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties )
1217 : ContextHandler2( rParent )
1218 , mrCustomShapeProperties( rCustomShapeProperties )
1222 ContextHandlerRef CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1224 switch( aElementToken )
1226 case A_TOKEN( avLst ): // CT_GeomGuideList adjust value list
1227 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1228 case A_TOKEN( gdLst ): // CT_GeomGuideList guide list
1229 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getGuideList() );
1230 case A_TOKEN( ahLst ): // CT_AdjustHandleList adjust handle list
1231 return new AdjustHandleListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustHandleList() );
1232 case A_TOKEN( cxnLst ): // CT_ConnectionSiteList connection site list
1233 return this;
1234 case A_TOKEN( rect ): // CT_GeomRectList geometry rect list
1236 GeomRect aGeomRect;
1237 aGeomRect.l = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_l ) );
1238 aGeomRect.t = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_t ) );
1239 aGeomRect.r = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_r ) );
1240 aGeomRect.b = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_b ) );
1241 mrCustomShapeProperties.getTextRect() = aGeomRect;
1243 break;
1244 case A_TOKEN( pathLst ): // CT_Path2DList 2d path list
1245 return new Path2DListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getSegments(), mrCustomShapeProperties.getPath2DList() );
1247 // from cxnLst:
1248 case A_TOKEN( cxn ): // CT_ConnectionSite
1250 ConnectionSite aConnectionSite;
1251 mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
1252 return new ConnectionSiteContext( *this, rAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
1255 return nullptr;
1258 // CT_PresetGeometry2D
1259 PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1260 : ContextHandler2( rParent )
1261 , mrCustomShapeProperties( rCustomShapeProperties )
1263 sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1264 OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1265 mrCustomShapeProperties.setShapePresetType( nShapeType );
1268 ContextHandlerRef PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1270 if ( aElementToken == A_TOKEN( avLst ) )
1271 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1272 else
1273 return this;
1276 // CT_PresetTextShape
1277 PresetTextShapeContext::PresetTextShapeContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1278 : ContextHandler2( rParent )
1279 , mrCustomShapeProperties( rCustomShapeProperties )
1281 sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1282 OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1283 mrCustomShapeProperties.setShapePresetType( nShapeType );
1286 ContextHandlerRef PresetTextShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1288 if ( aElementToken == A_TOKEN( avLst ) )
1289 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1290 else
1291 return this;
1296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */