LibreOffice Module oox (master) 1
customshapegeometry.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
22
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>
31#include <oox/token/namespaces.hxx>
32#include <oox/token/tokens.hxx>
33#include <unordered_map>
34
35using namespace ::oox::core;
36using namespace ::com::sun::star::uno;
37using namespace ::com::sun::star::drawing;
38using namespace ::com::sun::star::xml::sax;
39
40namespace oox::drawingml {
41
42namespace {
43
44enum FormulaCommand
45{
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
64};
65
66struct FormulaCommandNameTable
67{
68 const char* pS;
69 FormulaCommand pE;
70};
71
72}
73
74const FormulaCommandNameTable pFormulaCommandNameTable[] =
75{
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 }
94
95};
96typedef std::unordered_map< OUString, FormulaCommand > FormulaCommandHMap;
97
99
100static OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
101{
102 OUString aRet;
103 switch( rParameter.Type )
104 {
105 case EnhancedCustomShapeParameterType::NORMAL :
106 {
107 if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
108 {
109 double fValue = 0.0;
110 if ( rParameter.Value >>= fValue )
111 aRet = OUString::number( fValue );
112 }
113 else
114 {
115 sal_Int32 nValue = 0;
116 if ( rParameter.Value >>= nValue )
117 aRet = OUString::number( nValue );
118 }
119 }
120 break;
121 case EnhancedCustomShapeParameterType::EQUATION :
122 {
123 if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
124 {
125 sal_Int32 nFormulaIndex;
126 if ( rParameter.Value >>= nFormulaIndex )
127 {
128 aRet = "?"
129 + OUString::number( nFormulaIndex )
130 + " ";
131 }
132 }
133 else
134 {
135 // ups... we should have an index here and not the formula name
136 }
137 }
138 break;
139 case EnhancedCustomShapeParameterType::ADJUSTMENT :
140 {
141 if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
142 {
143 sal_Int32 nAdjustmentIndex;
144 if ( rParameter.Value >>= nAdjustmentIndex )
145 {
146 aRet = "$"
147 + OUString::number( nAdjustmentIndex )
148 + " ";
149 }
150 }
151 else
152 {
153 // ups... we should have an index here and not the formula name
154 }
155 }
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;
193 }
194 return aRet;
195}
196
197static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const OUString& rValue, bool bNoSymbols = true )
198{
199 css::drawing::EnhancedCustomShapeParameter aRet;
200 if ( !rValue.isEmpty() )
201 {
202 bool bConstant = true;
203 sal_Int32 nConstant = -1;
204 sal_Int32 nIntVal = 0;
205
206 // first check if it's a constant value
207 switch( AttributeConversion::decodeToken( rValue ) )
208 {
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;
217
218 case XML_b : // variable height of the shape defined in spPr
219 case XML_h :
220 {
221 if ( bNoSymbols )
222 {
223 CustomShapeGuide aGuide;
224 aGuide.maName = rValue;
225 aGuide.maFormula = "logheight" ;
226
227 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
228 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
229 }
230 else
231 aRet.Type = EnhancedCustomShapeParameterType::LOGHEIGHT; // TODO: HEIGHT needs to be implemented
232 }
233 break;
234
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
255 {
256 nIntVal += 2;
257
258 CustomShapeGuide aGuide;
259 aGuide.maName = rValue;
260 aGuide.maFormula = "logheight/" + OUString::number( nIntVal );
261
262 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
263 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
264 }
265 break;
266
267 case XML_t :
268 case XML_l :
269 {
270 nConstant = 0;
271 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
272 }
273 break;
274
275 case XML_ls : // longest side: max w h
276 {
277 CustomShapeGuide aGuide;
278 aGuide.maName = rValue;
279 aGuide.maFormula = "max(logwidth,logheight)";
280
281 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
282 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
283 }
284 break;
285 case XML_ss : // shortest side: min w h
286 {
287 CustomShapeGuide aGuide;
288 aGuide.maName = rValue;
289 aGuide.maFormula = "min(logwidth,logheight)";
290
291 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
292 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
293 }
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
311 {
312 nIntVal += 2;
313
314 CustomShapeGuide aGuide;
315 aGuide.maName = rValue;
316 aGuide.maFormula = "min(logwidth,logheight)/" + OUString::number( nIntVal );
317
318 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
319 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
320 }
321 break;
322
323 case XML_r : // variable width of the shape defined in spPr
324 case XML_w :
325 {
326 if ( bNoSymbols )
327 {
328 CustomShapeGuide aGuide;
329 aGuide.maName = rValue;
330 aGuide.maFormula = "logwidth" ;
331
332 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
333 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
334 }
335 else
336 aRet.Type = EnhancedCustomShapeParameterType::LOGWIDTH;
337 }
338 break;
339
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
366 {
367 nIntVal += 2;
368
369 CustomShapeGuide aGuide;
370 aGuide.maName = rValue;
371 aGuide.maFormula = "logwidth/" + OUString::number( nIntVal );
372
373 aRet.Value <<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide );
374 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
375 }
376 break;
377
378 default:
379 bConstant = false;
380 break;
381 }
382 if ( bConstant )
383 {
384 if (nConstant != -1) {
385 aRet.Value <<= nConstant;
386 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
387 }
388 }
389 else
390 {
391 sal_Unicode n = rValue[ 0 ];
392 if ( ( n == '+' ) || ( n == '-' ) )
393 {
394 if ( rValue.getLength() > 1 )
395 n = rValue[ 1 ];
396 }
397 if ( ( n >= '0' ) && ( n <= '9' ) )
398 { // seems to be a ST_Coordinate
399 aRet.Value <<= rValue.toInt32();
400 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
401 }
402 else
403 {
404 sal_Int32 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getAdjustmentGuideList(), rValue );
405 if ( nGuideIndex >= 0 )
406 {
407 aRet.Value <<= nGuideIndex;
408 aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
409 }
410 else
411 {
412 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), rValue );
413 if ( nGuideIndex >= 0 )
414 {
415 aRet.Value <<= nGuideIndex;
416 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
417 }
418 else
419 {
420 SAL_WARN("oox", "error: unhandled value " << rValue);
421 aRet.Value <<= rValue;
422 }
423 }
424 }
425 }
426 }
427 return aRet;
428}
429
430namespace {
431
432// CT_GeomGuideList
433class GeomGuideListContext : public ContextHandler2
434{
435public:
436 GeomGuideListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList );
437 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
438
439protected:
440 std::vector< CustomShapeGuide >& mrGuideList;
441 CustomShapeProperties& mrCustomShapeProperties;
442};
443
444}
445
446GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList )
447: ContextHandler2( rParent )
448, mrGuideList( rGuideList )
449, mrCustomShapeProperties( rCustomShapeProperties )
450{
451}
452
453static OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, std::u16string_view rSource )
454{
455 if ( !pCommandHashMap )
456 {
458 for(const FormulaCommandNameTable& i : pFormulaCommandNameTable)
459 (*pHM)[ OUString::createFromAscii( i.pS ) ] = i.pE;
460 pCommandHashMap = pHM;
461 }
462
463 std::vector< OUString > aTokens;
464 sal_Int32 nIndex = 0;
465 do
466 {
467 OUString aToken( o3tl::getToken(rSource, 0, ' ', nIndex ) );
468 if ( !aToken.isEmpty() )
469 aTokens.push_back( aToken );
470 }
471 while ( nIndex >= 0 );
472
473 OUString aEquation;
474 if ( !aTokens.empty() )
475 {
476 sal_Int32 i, nParameters = aTokens.size() - 1;
477 if ( nParameters > 3 )
478 nParameters = 3;
479
480 OUString sParameters[ 3 ];
481
482 for ( i = 0; i < nParameters; i++ )
483 sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], false ) );
484
485 const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
486 if ( aIter != pCommandHashMap->end() )
487 {
488 switch( aIter->second )
489 {
490 case FC_MULDIV :
491 {
492 if ( nParameters == 3 )
493 aEquation = sParameters[ 0 ] + "*" + sParameters[ 1 ]
494 + "/" + sParameters[ 2 ];
495 }
496 break;
497 case FC_PLUSMINUS :
498 {
499 if ( nParameters == 3 )
500 aEquation = sParameters[ 0 ] + "+" + sParameters[ 1 ]
501 + "-" + sParameters[ 2 ];
502 }
503 break;
504 case FC_PLUSDIV :
505 {
506 if ( nParameters == 3 )
507 aEquation = "(" + sParameters[ 0 ] + "+"
508 + sParameters[ 1 ] + ")/" + sParameters[ 2 ];
509 }
510 break;
511 case FC_IFELSE :
512 case FC_IFELSE1 :
513 {
514 if ( nParameters == 3 )
515 aEquation = "if(" + sParameters[ 0 ] + ","
516 + sParameters[ 1 ] + "," + sParameters[ 2 ] + ")";
517 }
518 break;
519 case FC_ABS :
520 {
521 if ( nParameters == 1 )
522 aEquation = "abs(" + sParameters[ 0 ] + ")";
523 }
524 break;
525 case FC_AT2 :
526 {
527 if ( nParameters == 2 )
528 aEquation = "(10800000*atan2(" + sParameters[ 1 ] + ","
529 + sParameters[ 0 ] + "))/pi";
530 }
531 break;
532 case FC_CAT2 :
533 {
534 if ( nParameters == 3 )
535 aEquation = sParameters[ 0 ] + "*(cos(atan2(" +
536 sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
537 }
538 break;
539 case FC_COS :
540 {
541 if ( nParameters == 2 )
542 aEquation = sParameters[ 0 ] + "*cos(pi*(" +
543 sParameters[ 1 ] + ")/10800000)";
544 }
545 break;
546 case FC_MAX :
547 {
548 if ( nParameters == 2 )
549 aEquation = "max(" + sParameters[ 0 ] + "," +
550 sParameters[ 1 ] + ")";
551 }
552 break;
553 case FC_MIN :
554 {
555 if ( nParameters == 2 )
556 aEquation = "min(" + sParameters[ 0 ] + "," +
557 sParameters[ 1 ] + ")";
558 }
559 break;
560 case FC_MOD :
561 {
562 if ( nParameters == 3 )
563 aEquation = "sqrt("
564 + sParameters[ 0 ] + "*" + sParameters[ 0 ] + "+"
565 + sParameters[ 1 ] + "*" + sParameters[ 1 ] + "+"
566 + sParameters[ 2 ] + "*" + sParameters[ 2 ] + ")";
567 }
568 break;
569 case FC_PIN :
570 {
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 ] + "))";
576 }
577 break;
578 case FC_SAT2 :
579 {
580 if ( nParameters == 3 )
581 aEquation = sParameters[ 0 ] + "*(sin(atan2(" +
582 sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
583 }
584 break;
585 case FC_SIN :
586 {
587 if ( nParameters == 2 )
588 aEquation = sParameters[ 0 ] + "*sin(pi*(" +
589 sParameters[ 1 ] + ")/10800000)";
590 }
591 break;
592 case FC_SQRT :
593 {
594 if ( nParameters == 1 )
595 aEquation = "sqrt(" + sParameters[ 0 ] + ")";
596 }
597 break;
598 case FC_TAN :
599 {
600 if ( nParameters == 2 )
601 aEquation = sParameters[ 0 ] + "*tan(pi*(" +
602 sParameters[ 1 ] + ")/10800000)";
603 }
604 break;
605 case FC_VAL :
606 {
607 if ( nParameters == 1 )
608 aEquation = sParameters[ 0 ];
609 }
610 break;
611 default :
612 break;
613 }
614 }
615 }
616 return aEquation;
617}
618
619ContextHandlerRef GeomGuideListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
620{
621 if ( aElementToken == A_TOKEN( gd ) ) // CT_GeomGuide
622 {
623 CustomShapeGuide aGuide;
624 aGuide.maName = rAttribs.getStringDefaulted( XML_name );
625 aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_fmla ) );
626 mrGuideList.push_back( aGuide );
627 }
628 return this;
629}
630
631static const OUString& GetGeomGuideName( const OUString& rValue )
632{
633 return rValue;
634}
635
636namespace {
637
638// CT_AdjPoint2D
639class AdjPoint2DContext : public ContextHandler2
640{
641public:
642 AdjPoint2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
643};
644
645}
646
647AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
648: ContextHandler2( rParent )
649{
650 rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getStringDefaulted( XML_x ) );
651 rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getStringDefaulted( XML_y ) );
652}
653
654namespace {
655
656// CT_XYAdjustHandle
657class XYAdjustHandleContext : public ContextHandler2
658{
659public:
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;
662
663protected:
664 AdjustHandle& mrAdjustHandle;
665 CustomShapeProperties& mrCustomShapeProperties;
666};
667
668}
669
670XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
671: ContextHandler2( rParent )
672, mrAdjustHandle( rAdjustHandle )
673, mrCustomShapeProperties( rCustomShapeProperties )
674{
675 if ( rAttribs.hasAttribute( XML_gdRefX ) )
676 {
677 mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getStringDefaulted( XML_gdRefX) );
678 }
679 if ( rAttribs.hasAttribute( XML_minX ) )
680 {
681 mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_minX) );
682 }
683 if ( rAttribs.hasAttribute( XML_maxX ) )
684 {
685 mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_maxX) );
686 }
687 if ( rAttribs.hasAttribute( XML_gdRefY ) )
688 {
689 mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getStringDefaulted( XML_gdRefY) );
690 }
691 if ( rAttribs.hasAttribute( XML_minY ) )
692 {
693 mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_minY) );
694 }
695 if ( rAttribs.hasAttribute( XML_maxY ) )
696 {
697 mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_maxY) );
698 }
699}
700
701ContextHandlerRef XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
702{
703 if ( aElementToken == A_TOKEN( pos ) )
704 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
705 return nullptr;
706}
707
708namespace {
709
710// CT_PolarAdjustHandle
711class PolarAdjustHandleContext : public ContextHandler2
712{
713public:
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;
716
717protected:
718 AdjustHandle& mrAdjustHandle;
719 CustomShapeProperties& mrCustomShapeProperties;
720};
721
722}
723
724PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
725: ContextHandler2( rParent )
726, mrAdjustHandle( rAdjustHandle )
727, mrCustomShapeProperties( rCustomShapeProperties )
728{
729 if ( rAttribs.hasAttribute( XML_gdRefR ) )
730 {
731 mrAdjustHandle.polar = true ;
732 mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getStringDefaulted( XML_gdRefR) );
733 }
734 if ( rAttribs.hasAttribute( XML_minR ) )
735 {
736 mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_minR) );
737 }
738 if ( rAttribs.hasAttribute( XML_maxR ) )
739 {
740 mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_maxR) );
741 }
742 if ( rAttribs.hasAttribute( XML_gdRefAng ) )
743 {
744 mrAdjustHandle.polar = true ;
745 mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getStringDefaulted( XML_gdRefAng) );
746 }
747 if ( rAttribs.hasAttribute( XML_minAng ) )
748 {
749 mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_minAng) );
750 }
751 if ( rAttribs.hasAttribute( XML_maxAng ) )
752 {
753 mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_maxAng) );
754 }
755}
756
757ContextHandlerRef PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
758{
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;
763}
764
765namespace {
766
767// CT_AdjustHandleList
768class AdjustHandleListContext : public ContextHandler2
769{
770public:
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;
773
774protected:
775 std::vector< AdjustHandle >& mrAdjustHandleList;
776 CustomShapeProperties& mrCustomShapeProperties;
777};
778
779}
780
781AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
782: ContextHandler2( rParent )
783, mrAdjustHandleList( rAdjustHandleList )
784, mrCustomShapeProperties( rCustomShapeProperties )
785{
786}
787
788ContextHandlerRef AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
789{
790 if ( aElementToken == A_TOKEN( ahXY ) ) // CT_XYAdjustHandle
791 {
792 AdjustHandle aAdjustHandle( false );
793 mrAdjustHandleList.push_back( aAdjustHandle );
794 return new XYAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
795 }
796 else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
797 {
798 AdjustHandle aAdjustHandle( true );
799 mrAdjustHandleList.push_back( aAdjustHandle );
800 return new PolarAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
801 }
802 return nullptr;
803}
804
805namespace {
806
807// CT_ConnectionSite
808class ConnectionSiteContext : public ContextHandler2
809{
810public:
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;
813
814protected:
815 ConnectionSite& mrConnectionSite;
816 CustomShapeProperties& mrCustomShapeProperties;
817};
818
819}
820
821ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
822: ContextHandler2( rParent )
823, mrConnectionSite( rConnectionSite )
824, mrCustomShapeProperties( rCustomShapeProperties )
825{
826 mrConnectionSite.ang = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_ang ) );
827}
828
829ContextHandlerRef ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
830{
831 if ( aElementToken == A_TOKEN( pos ) )
832 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
833 return nullptr;
834}
835
836namespace {
837
838// CT_Path2DMoveTo
839class Path2DMoveToContext : public ContextHandler2
840{
841public:
842 Path2DMoveToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
843 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
844
845protected:
846 EnhancedCustomShapeParameterPair& mrAdjPoint2D;
847 CustomShapeProperties& mrCustomShapeProperties;
848};
849
850}
851
852Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
853: ContextHandler2( rParent )
854, mrAdjPoint2D( rAdjPoint2D )
855, mrCustomShapeProperties( rCustomShapeProperties )
856{
857}
858
859ContextHandlerRef Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
860{
861 if ( aElementToken == A_TOKEN( pt ) )
862 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
863 return nullptr;
864}
865
866namespace {
867
868// CT_Path2DLineTo
869class Path2DLineToContext : public ContextHandler2
870{
871public:
872 Path2DLineToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
873 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
874
875protected:
876 EnhancedCustomShapeParameterPair& mrAdjPoint2D;
877 CustomShapeProperties& mrCustomShapeProperties;
878};
879
880}
881
882Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
883: ContextHandler2( rParent )
884, mrAdjPoint2D( rAdjPoint2D )
885, mrCustomShapeProperties( rCustomShapeProperties )
886{
887}
888
889ContextHandlerRef Path2DLineToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
890{
891 if ( aElementToken == A_TOKEN( pt ) )
892 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
893 return nullptr;
894}
895
896namespace {
897
898// CT_Path2DQuadBezierTo
899class Path2DQuadBezierToContext : public ContextHandler2
900{
901public:
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;
904
905protected:
906 EnhancedCustomShapeParameterPair& mrPt1;
907 EnhancedCustomShapeParameterPair& mrPt2;
909 CustomShapeProperties& mrCustomShapeProperties;
910};
911
912}
913
914Path2DQuadBezierToContext::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 )
923{
924}
925
926ContextHandlerRef Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
927{
928 if ( aElementToken == A_TOKEN( pt ) )
929 return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
930 return nullptr;
931}
932
933namespace {
934
935// CT_Path2DCubicBezierTo
936class Path2DCubicBezierToContext : public ContextHandler2
937{
938public:
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;
942
943protected:
944 CustomShapeProperties& mrCustomShapeProperties;
945 EnhancedCustomShapeParameterPair& mrControlPt1;
946 EnhancedCustomShapeParameterPair& mrControlPt2;
947 EnhancedCustomShapeParameterPair& mrEndPt;
948 int nCount;
949};
950
951}
952
953Path2DCubicBezierToContext::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 )
963{
964}
965
966ContextHandlerRef Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
967{
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;
972}
973
974namespace {
975
976// CT_Path2DContext
977class Path2DContext : public ContextHandler2
978{
979public:
980 Path2DContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< css::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D );
981 virtual void onEndElement() override;
983 onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
984
985protected:
986 Path2D& mrPath2D;
987 std::vector< css::drawing::EnhancedCustomShapeSegment >& mrSegments;
988 CustomShapeProperties& mrCustomShapeProperties;
989};
990
991}
992
993Path2DContext::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 )
998{
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 );
1004}
1005
1006void Path2DContext::onEndElement()
1007{
1008 EnhancedCustomShapeSegment aNewSegment;
1009 switch ( mrPath2D.fill )
1010 {
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;
1026 }
1027 if (mrPath2D.fill != XML_norm) {
1028 aNewSegment.Count = 0;
1029 mrSegments.push_back( aNewSegment );
1030 }
1031 if ( !mrPath2D.stroke )
1032 {
1033 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
1034 aNewSegment.Count = 0;
1035 mrSegments.push_back( aNewSegment );
1036 }
1037 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
1038 aNewSegment.Count = 0;
1039 mrSegments.push_back( aNewSegment );
1040}
1041
1042
1043ContextHandlerRef Path2DContext::onCreateContext( sal_Int32 aElementToken,
1044 const AttributeList& rAttribs )
1045{
1046 switch( aElementToken )
1047 {
1048 case A_TOKEN( close ) :
1049 {
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 );
1056 }
1057 }
1058 break;
1059 case A_TOKEN( moveTo ) :
1060 {
1061 EnhancedCustomShapeSegment aNewSegment;
1062 aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
1063 aNewSegment.Count = 1;
1064 mrSegments.push_back( aNewSegment );
1065
1066 EnhancedCustomShapeParameterPair aAdjPoint2D;
1067 mrPath2D.parameter.push_back( aAdjPoint2D );
1068 return new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1069 }
1070 break;
1071 case A_TOKEN( lnTo ) :
1072 {
1073 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
1074 mrSegments.back().Count++;
1075 else
1076 {
1077 EnhancedCustomShapeSegment aSegment;
1078 aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
1079 aSegment.Count = 1;
1080 mrSegments.push_back( aSegment );
1081 }
1082 EnhancedCustomShapeParameterPair aAdjPoint2D;
1083 mrPath2D.parameter.push_back( aAdjPoint2D );
1084 return new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1085 }
1086 break;
1087 case A_TOKEN( arcTo ) : // CT_Path2DArcTo
1088 {
1089 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCANGLETO ) )
1090 mrSegments.back().Count++;
1091 else
1092 {
1093 EnhancedCustomShapeSegment aSegment;
1094 aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCANGLETO;
1095 aSegment.Count = 1;
1096 mrSegments.push_back( aSegment );
1097 }
1098
1099 EnhancedCustomShapeParameterPair aScale;
1100 EnhancedCustomShapeParameterPair aAngles;
1101
1102 aScale.First = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_wR ) );
1103 aScale.Second = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getStringDefaulted( XML_hR ) );
1104
1105 CustomShapeGuide aGuide;
1106 sal_Int32 nArcNum = mrCustomShapeProperties.getArcNum();
1107
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 <<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide );
1114 aAngles.First.Type = EnhancedCustomShapeParameterType::EQUATION;
1115
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 <<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide );
1122 aAngles.Second.Type = EnhancedCustomShapeParameterType::EQUATION;
1123
1124 mrPath2D.parameter.push_back( aScale );
1125 mrPath2D.parameter.push_back( aAngles );
1126 }
1127 break;
1128 case A_TOKEN( quadBezTo ) :
1129 {
1130 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
1131 mrSegments.back().Count++;
1132 else
1133 {
1134 EnhancedCustomShapeSegment aSegment;
1135 aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
1136 aSegment.Count = 1;
1137 mrSegments.push_back( aSegment );
1138 }
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() );
1146 }
1147 break;
1148 case A_TOKEN( cubicBezTo ) :
1149 {
1150 if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
1151 mrSegments.back().Count++;
1152 else
1153 {
1154 EnhancedCustomShapeSegment aSegment;
1155 aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
1156 aSegment.Count = 1;
1157 mrSegments.push_back( aSegment );
1158 }
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() );
1169 }
1170 break;
1171 }
1172 return nullptr;
1173}
1174
1175namespace {
1176
1177// CT_Path2DList
1178class Path2DListContext : public ContextHandler2
1179{
1180public:
1181 Path2DListContext( ContextHandler2Helper const & rParent, CustomShapeProperties & rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1182 std::vector< Path2D >& rPath2DList );
1183
1184 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) override;
1185
1186protected:
1187
1188 CustomShapeProperties& mrCustomShapeProperties;
1189 std::vector< css::drawing::EnhancedCustomShapeSegment >& mrSegments;
1190 std::vector< Path2D >& mrPath2DList;
1191};
1192
1193}
1194
1195Path2DListContext:: 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 )
1201{
1202}
1203
1204ContextHandlerRef Path2DListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1205{
1206 if ( aElementToken == A_TOKEN( path ) )
1207 {
1208 Path2D aPath2D;
1209 mrPath2DList.push_back( aPath2D );
1210 return new Path2DContext( *this, rAttribs, mrCustomShapeProperties, mrSegments, mrPath2DList.back() );
1211 }
1212 return nullptr;
1213}
1214
1215// CT_CustomGeometry2D
1216CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper const & rParent, CustomShapeProperties& rCustomShapeProperties )
1217: ContextHandler2( rParent )
1218, mrCustomShapeProperties( rCustomShapeProperties )
1219{
1220}
1221
1223{
1224 switch( aElementToken )
1225 {
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
1235 {
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 ) );
1242 }
1243 break;
1244 case A_TOKEN( pathLst ): // CT_Path2DList 2d path list
1246
1247 // from cxnLst:
1248 case A_TOKEN( cxn ): // CT_ConnectionSite
1249 {
1250 ConnectionSite aConnectionSite;
1251 mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
1252 return new ConnectionSiteContext( *this, rAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
1253 }
1254 }
1255 return nullptr;
1256}
1257
1258// CT_PresetGeometry2D
1260: ContextHandler2( rParent )
1261, mrCustomShapeProperties( rCustomShapeProperties )
1262{
1263 sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1264 OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1266}
1267
1269{
1270 if ( aElementToken == A_TOKEN( avLst ) )
1271 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1272 else
1273 return this;
1274}
1275
1276// CT_PresetTextShape
1278: ContextHandler2( rParent )
1279, mrCustomShapeProperties( rCustomShapeProperties )
1280{
1281 sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1282 OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1284}
1285
1287{
1288 if ( aElementToken == A_TOKEN( avLst ) )
1289 return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1290 else
1291 return this;
1292}
1293
1294}
1295
1296/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static sal_Int32 decodeToken(std::u16string_view rValue)
Returns the XML token identifier from the passed string.
Provides access to attribute values of an element.
OUString getStringDefaulted(sal_Int32 nAttrToken) const
Returns the string value of the specified attribute, returns an empty string if attribute not present...
std::optional< sal_Int32 > getToken(sal_Int32 nAttrToken) const
Returns the token identifier of the value of the specified attribute.
Helper class that provides a context stack.
virtual ::oox::core::ContextHandlerRef onCreateContext(::sal_Int32 aElementToken, const ::oox::AttributeList &rAttribs) override
std::vector< css::drawing::EnhancedCustomShapeSegment > & getSegments()
std::vector< ConnectionSite > & getConnectionSiteList()
void setShapePresetType(sal_Int32 nShapePresetType)
std::vector< CustomShapeGuide > & getGuideList()
std::optional< GeomRect > & getTextRect()
static sal_Int32 GetCustomShapeGuideValue(const std::vector< CustomShapeGuide > &rGuideList, std::u16string_view rFormulaName)
std::vector< AdjustHandle > & getAdjustHandleList()
std::vector< CustomShapeGuide > & getAdjustmentGuideList()
static sal_Int32 SetCustomShapeGuideValue(std::vector< CustomShapeGuide > &rGuideList, const CustomShapeGuide &rGuide)
PresetShapeGeometryContext(::oox::core::ContextHandler2Helper const &rParent, const ::oox::AttributeList &rAttributes, CustomShapeProperties &rCustomShapeProperties)
virtual ::oox::core::ContextHandlerRef onCreateContext(::sal_Int32 aElementToken, const ::oox::AttributeList &rAttribs) override
PresetTextShapeContext(::oox::core::ContextHandler2Helper const &rParent, const ::oox::AttributeList &rAttributes, CustomShapeProperties &rCustomShapeProperties)
virtual ::oox::core::ContextHandlerRef onCreateContext(::sal_Int32 aElementToken, const ::oox::AttributeList &rAttribs) override
std::vector< AdjustHandle > & mrAdjustHandleList
EnhancedCustomShapeParameterPair & mrAdjPoint2D
std::vector< CustomShapeGuide > & mrGuideList
Path2D & mrPath2D
int nCount
EnhancedCustomShapeParameterPair & mrPt1
const char * pS
EnhancedCustomShapeParameterPair & mrControlPt1
ConnectionSite & mrConnectionSite
std::vector< Path2D > & mrPath2DList
EnhancedCustomShapeParameterPair & mrControlPt2
std::vector< css::drawing::EnhancedCustomShapeSegment > & mrSegments
FormulaCommand pE
AdjustHandle & mrAdjustHandle
EnhancedCustomShapeParameterPair & mrEndPt
CustomShapeProperties & mrCustomShapeProperties
EnhancedCustomShapeParameterPair & mrPt2
sal_Int16 nValue
sal_Int32 nIndex
sal_Int64 n
#define SAL_WARN(area, stream)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
::rtl::Reference< ContextHandler > ContextHandlerRef
static const OUString & GetGeomGuideName(const OUString &rValue)
static const FormulaCommandHMap * pCommandHashMap
static EnhancedCustomShapeParameter GetAdjCoordinate(CustomShapeProperties &rCustomShapeProperties, const OUString &rValue, bool bNoSymbols=true)
const FormulaCommandNameTable pFormulaCommandNameTable[]
static OUString convertToOOEquation(CustomShapeProperties &rCustomShapeProperties, std::u16string_view rSource)
std::unordered_map< OUString, FormulaCommand > FormulaCommandHMap
static OUString GetFormulaParameter(const EnhancedCustomShapeParameter &rParameter)
XML_norm
XML_none
css::drawing::EnhancedCustomShapeParameter l
css::drawing::EnhancedCustomShapeParameter b
css::drawing::EnhancedCustomShapeParameter r
css::drawing::EnhancedCustomShapeParameter t
sal_uInt16 sal_Unicode