1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <drawingml/customshapegeometry.hxx>
21 #include <drawingml/customshapeproperties.hxx>
23 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
24 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
25 #include <com/sun/star/xml/sax/FastToken.hpp>
26 #include <osl/diagnose.h>
27 #include <sal/log.hxx>
28 #include <oox/helper/helper.hxx>
29 #include <oox/helper/attributelist.hxx>
30 #include <oox/helper/propertymap.hxx>
31 #include <oox/token/namespaces.hxx>
32 #include <oox/token/tokens.hxx>
33 #include <unordered_map>
35 using namespace ::oox::core
;
36 using namespace ::com::sun::star::uno
;
37 using namespace ::com::sun::star::drawing
;
38 using namespace ::com::sun::star::xml::sax
;
40 namespace oox
{ namespace drawingml
{
63 struct FormularCommandNameTable
66 FormularCommand
const pE
;
68 static const FormularCommandNameTable pFormularCommandNameTable
[] =
71 { "+-", FC_PLUSMINUS
},
73 { "ifelse", FC_IFELSE
},
90 typedef std::unordered_map
< OUString
, FormularCommand
> FormulaCommandHMap
;
92 static const FormulaCommandHMap
* pCommandHashMap
;
94 static OUString
GetFormulaParameter( const EnhancedCustomShapeParameter
& rParameter
)
97 switch( rParameter
.Type
)
99 case EnhancedCustomShapeParameterType::NORMAL
:
101 if ( rParameter
.Value
.getValueTypeClass() == TypeClass_DOUBLE
)
104 if ( rParameter
.Value
>>= fValue
)
105 aRet
= OUString::number( fValue
);
109 sal_Int32 nValue
= 0;
110 if ( rParameter
.Value
>>= nValue
)
111 aRet
= OUString::number( nValue
);
115 case EnhancedCustomShapeParameterType::EQUATION
:
117 if ( rParameter
.Value
.getValueTypeClass() == TypeClass_LONG
)
119 sal_Int32 nFormulaIndex
;
120 if ( rParameter
.Value
>>= nFormulaIndex
)
123 + OUString::number( nFormulaIndex
)
129 // ups... we should have an index here and not the formula name
133 case EnhancedCustomShapeParameterType::ADJUSTMENT
:
135 if ( rParameter
.Value
.getValueTypeClass() == TypeClass_LONG
)
137 sal_Int32 nAdjustmentIndex
;
138 if ( rParameter
.Value
>>= nAdjustmentIndex
)
141 + OUString::number( nAdjustmentIndex
)
147 // ups... we should have an index here and not the formula name
151 case EnhancedCustomShapeParameterType::LEFT
:
154 case EnhancedCustomShapeParameterType::TOP
:
157 case EnhancedCustomShapeParameterType::RIGHT
:
160 case EnhancedCustomShapeParameterType::BOTTOM
:
163 case EnhancedCustomShapeParameterType::XSTRETCH
:
166 case EnhancedCustomShapeParameterType::YSTRETCH
:
169 case EnhancedCustomShapeParameterType::HASSTROKE
:
172 case EnhancedCustomShapeParameterType::HASFILL
:
175 case EnhancedCustomShapeParameterType::WIDTH
:
178 case EnhancedCustomShapeParameterType::HEIGHT
:
181 case EnhancedCustomShapeParameterType::LOGWIDTH
:
184 case EnhancedCustomShapeParameterType::LOGHEIGHT
:
191 static EnhancedCustomShapeParameter
GetAdjCoordinate( CustomShapeProperties
& rCustomShapeProperties
, const OUString
& rValue
, bool bNoSymbols
= true )
193 css::drawing::EnhancedCustomShapeParameter aRet
;
194 if ( !rValue
.isEmpty() )
196 bool bConstant
= true;
197 sal_Int32 nConstant
= -1;
198 sal_Int32 nIntVal
= 0;
200 // first check if it's a constant value
201 switch( AttributeConversion::decodeToken( rValue
) )
203 case XML_3cd4
: nConstant
= 270 * 60000; break;
204 case XML_3cd8
: nConstant
= 135 * 60000; break;
205 case XML_5cd8
: nConstant
= 225 * 60000; break;
206 case XML_7cd8
: nConstant
= 315 * 60000; break;
207 case XML_cd2
: nConstant
= 180 * 60000; break;
208 case XML_cd3
: nConstant
= 120 * 60000; break;
209 case XML_cd4
: nConstant
= 90 * 60000; break;
210 case XML_cd8
: nConstant
= 45 * 60000; break;
212 case XML_b
: // variable height of the shape defined in spPr
217 CustomShapeGuide aGuide
;
218 aGuide
.maName
= rValue
;
219 aGuide
.maFormula
= "logheight" ;
221 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
222 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
225 aRet
.Type
= EnhancedCustomShapeParameterType::LOGHEIGHT
; // TODO: HEIGHT needs to be implemented
230 nIntVal
+= 2; // */ h 1.0 10.0
232 case XML_hd8
: // */ h 1.0 8.0
235 case XML_hd6
: // */ h 1.0 6.0
238 case XML_hd5
: // */ h 1.0 5.0
241 case XML_hd4
: // */ h 1.0 4.0
244 case XML_hd3
: // */ h 1.0 3.0
247 case XML_hd2
: // */ h 1.0 2.0
248 case XML_vc
: // */ h 1.0 2.0
252 CustomShapeGuide aGuide
;
253 aGuide
.maName
= rValue
;
254 aGuide
.maFormula
= "logheight/" + OUString::number( nIntVal
);
256 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
257 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
265 aRet
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
269 case XML_ls
: // longest side: max w h
271 CustomShapeGuide aGuide
;
272 aGuide
.maName
= rValue
;
273 aGuide
.maFormula
= "max(logwidth,logheight)";
275 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
276 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
279 case XML_ss
: // shortest side: min w h
281 CustomShapeGuide aGuide
;
282 aGuide
.maName
= rValue
;
283 aGuide
.maFormula
= "min(logwidth,logheight)";
285 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
286 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
289 case XML_ssd32
: // */ ss 1.0 32.0
292 case XML_ssd16
: // */ ss 1.0 16.0
295 case XML_ssd8
: // */ ss 1.0 8.0
298 case XML_ssd6
: // */ ss 1.0 6.0
301 case XML_ssd4
: // */ ss 1.0 4.0
304 case XML_ssd2
: // */ ss 1.0 2.0
308 CustomShapeGuide aGuide
;
309 aGuide
.maName
= rValue
;
310 aGuide
.maFormula
= "min(logwidth,logheight)/" + OUString::number( nIntVal
);
312 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
313 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
317 case XML_r
: // variable width of the shape defined in spPr
322 CustomShapeGuide aGuide
;
323 aGuide
.maName
= rValue
;
324 aGuide
.maFormula
= "logwidth" ;
326 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
327 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
330 aRet
.Type
= EnhancedCustomShapeParameterType::LOGWIDTH
;
334 case XML_wd32
: // */ w 1.0 32.0
337 case XML_wd12
: // */ w 1.0 12.0
340 case XML_wd10
: // */ w 1.0 10.0
343 case XML_wd8
: // */ w 1.0 8.0
346 case XML_wd6
: // */ w 1.0 6.0
349 case XML_wd5
: // */ w 1.0 5.0
352 case XML_wd4
: // */ w 1.0 4.0
355 case XML_wd3
: // */ w 1.0 3.0
358 case XML_hc
: // */ w 1.0 2.0
359 case XML_wd2
: // */ w 1.0 2.0
363 CustomShapeGuide aGuide
;
364 aGuide
.maName
= rValue
;
365 aGuide
.maFormula
= "logwidth/" + OUString::number( nIntVal
);
367 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
368 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
378 if (nConstant
!= -1) {
379 aRet
.Value
<<= nConstant
;
380 aRet
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
385 sal_Unicode n
= rValue
[ 0 ];
386 if ( ( n
== '+' ) || ( n
== '-' ) )
388 if ( rValue
.getLength() > 1 )
391 if ( ( n
>= '0' ) && ( n
<= '9' ) )
392 { // seems to be a ST_Coordinate
393 aRet
.Value
<<= rValue
.toInt32();
394 aRet
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
398 sal_Int32 nGuideIndex
= CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties
.getAdjustmentGuideList(), rValue
);
399 if ( nGuideIndex
>= 0 )
401 aRet
.Value
<<= nGuideIndex
;
402 aRet
.Type
= EnhancedCustomShapeParameterType::ADJUSTMENT
;
406 nGuideIndex
= CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), rValue
);
407 if ( nGuideIndex
>= 0 )
409 aRet
.Value
<<= nGuideIndex
;
410 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
414 SAL_WARN("oox", "error: unhandled value " << rValue
);
415 aRet
.Value
<<= rValue
;
425 class GeomGuideListContext
: public ContextHandler2
428 GeomGuideListContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< CustomShapeGuide
>& rGuideList
);
429 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
432 std::vector
< CustomShapeGuide
>& mrGuideList
;
433 CustomShapeProperties
& mrCustomShapeProperties
;
436 GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< CustomShapeGuide
>& rGuideList
)
437 : ContextHandler2( rParent
)
438 , mrGuideList( rGuideList
)
439 , mrCustomShapeProperties( rCustomShapeProperties
)
443 static OUString
convertToOOEquation( CustomShapeProperties
& rCustomShapeProperties
, const OUString
& rSource
)
445 if ( !pCommandHashMap
)
447 FormulaCommandHMap
* pHM
= new FormulaCommandHMap
;
448 for(const FormularCommandNameTable
& i
: pFormularCommandNameTable
)
449 (*pHM
)[ OUString::createFromAscii( i
.pS
) ] = i
.pE
;
450 pCommandHashMap
= pHM
;
453 std::vector
< OUString
> aTokens
;
454 sal_Int32 nIndex
= 0;
457 OUString
aToken( rSource
.getToken( 0, ' ', nIndex
) );
458 if ( !aToken
.isEmpty() )
459 aTokens
.push_back( aToken
);
461 while ( nIndex
>= 0 );
464 if ( !aTokens
.empty() )
466 sal_Int32 i
, nParameters
= aTokens
.size() - 1;
467 if ( nParameters
> 3 )
470 OUString sParameters
[ 3 ];
472 for ( i
= 0; i
< nParameters
; i
++ )
473 sParameters
[ i
] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties
, aTokens
[ i
+ 1 ], false ) );
475 const FormulaCommandHMap::const_iterator
aIter( pCommandHashMap
->find( aTokens
[ 0 ] ) );
476 if ( aIter
!= pCommandHashMap
->end() )
478 switch( aIter
->second
)
482 if ( nParameters
== 3 )
483 aEquation
= sParameters
[ 0 ] + "*" + sParameters
[ 1 ]
484 + "/" + sParameters
[ 2 ];
489 if ( nParameters
== 3 )
490 aEquation
= sParameters
[ 0 ] + "+" + sParameters
[ 1 ]
491 + "-" + sParameters
[ 2 ];
496 if ( nParameters
== 3 )
497 aEquation
= "(" + sParameters
[ 0 ] + "+"
498 + sParameters
[ 1 ] + ")/" + sParameters
[ 2 ];
504 if ( nParameters
== 3 )
505 aEquation
= "if(" + sParameters
[ 0 ] + ","
506 + sParameters
[ 1 ] + "," + sParameters
[ 2 ] + ")";
511 if ( nParameters
== 1 )
512 aEquation
= "abs(" + sParameters
[ 0 ] + ")";
517 if ( nParameters
== 2 )
518 aEquation
= "(10800000*atan2(" + sParameters
[ 1 ] + ","
519 + sParameters
[ 0 ] + "))/pi";
524 if ( nParameters
== 3 )
525 aEquation
= sParameters
[ 0 ] + "*(cos(atan2(" +
526 sParameters
[ 2 ] + "," + sParameters
[ 1 ] + ")))";
531 if ( nParameters
== 2 )
532 aEquation
= sParameters
[ 0 ] + "*cos(pi*(" +
533 sParameters
[ 1 ] + ")/10800000)";
538 if ( nParameters
== 2 )
539 aEquation
= "max(" + sParameters
[ 0 ] + "," +
540 sParameters
[ 1 ] + ")";
545 if ( nParameters
== 2 )
546 aEquation
= "min(" + sParameters
[ 0 ] + "," +
547 sParameters
[ 1 ] + ")";
552 if ( nParameters
== 3 )
554 + sParameters
[ 0 ] + "*" + sParameters
[ 0 ] + "+"
555 + sParameters
[ 1 ] + "*" + sParameters
[ 1 ] + "+"
556 + sParameters
[ 2 ] + "*" + sParameters
[ 2 ] + ")";
561 if ( nParameters
== 3 ) // if(x-y,x,if(y-z,z,y))
562 aEquation
= "if(" + sParameters
[ 0 ] + "-" + sParameters
[ 1 ]
563 + "," + sParameters
[ 0 ] + ",if(" + sParameters
[ 2 ]
564 + "-" + sParameters
[ 1 ] + "," + sParameters
[ 1 ]
565 + "," + sParameters
[ 2 ] + "))";
570 if ( nParameters
== 3 )
571 aEquation
= sParameters
[ 0 ] + "*(sin(atan2(" +
572 sParameters
[ 2 ] + "," + sParameters
[ 1 ] + ")))";
577 if ( nParameters
== 2 )
578 aEquation
= sParameters
[ 0 ] + "*sin(pi*(" +
579 sParameters
[ 1 ] + ")/10800000)";
584 if ( nParameters
== 1 )
585 aEquation
= "sqrt(" + sParameters
[ 0 ] + ")";
590 if ( nParameters
== 2 )
591 aEquation
= sParameters
[ 0 ] + "*tan(pi*(" +
592 sParameters
[ 1 ] + ")/10800000)";
597 if ( nParameters
== 1 )
598 aEquation
= sParameters
[ 0 ];
609 ContextHandlerRef
GeomGuideListContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
611 if ( aElementToken
== A_TOKEN( gd
) ) // CT_GeomGuide
613 CustomShapeGuide aGuide
;
614 aGuide
.maName
= rAttribs
.getString( XML_name
).get();
615 aGuide
.maFormula
= convertToOOEquation( mrCustomShapeProperties
, rAttribs
.getString( XML_fmla
).get() );
616 mrGuideList
.push_back( aGuide
);
621 static const OUString
& GetGeomGuideName( const OUString
& rValue
)
627 class AdjPoint2DContext
: public ContextHandler2
630 AdjPoint2DContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
);
633 AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
)
634 : ContextHandler2( rParent
)
636 rAdjPoint2D
.First
= GetAdjCoordinate( rCustomShapeProperties
, rAttribs
.getString( XML_x
).get() );
637 rAdjPoint2D
.Second
= GetAdjCoordinate( rCustomShapeProperties
, rAttribs
.getString( XML_y
).get() );
641 class XYAdjustHandleContext
: public ContextHandler2
644 XYAdjustHandleContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, AdjustHandle
& rAdjustHandle
);
645 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
648 AdjustHandle
& mrAdjustHandle
;
649 CustomShapeProperties
& mrCustomShapeProperties
;
652 XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, AdjustHandle
& rAdjustHandle
)
653 : ContextHandler2( rParent
)
654 , mrAdjustHandle( rAdjustHandle
)
655 , mrCustomShapeProperties( rCustomShapeProperties
)
657 if ( rAttribs
.hasAttribute( XML_gdRefX
) )
659 mrAdjustHandle
.gdRef1
= GetGeomGuideName( rAttribs
.getString( XML_gdRefX
, "" ) );
661 if ( rAttribs
.hasAttribute( XML_minX
) )
663 mrAdjustHandle
.min1
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_minX
, "" ) );
665 if ( rAttribs
.hasAttribute( XML_maxX
) )
667 mrAdjustHandle
.max1
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_maxX
, "" ) );
669 if ( rAttribs
.hasAttribute( XML_gdRefY
) )
671 mrAdjustHandle
.gdRef2
= GetGeomGuideName( rAttribs
.getString( XML_gdRefY
, "" ) );
673 if ( rAttribs
.hasAttribute( XML_minY
) )
675 mrAdjustHandle
.min2
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_minY
, "" ) );
677 if ( rAttribs
.hasAttribute( XML_maxY
) )
679 mrAdjustHandle
.max2
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_maxY
, "" ) );
683 ContextHandlerRef
XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
685 if ( aElementToken
== A_TOKEN( pos
) )
686 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjustHandle
.pos
); // CT_AdjPoint2D
690 // CT_PolarAdjustHandle
691 class PolarAdjustHandleContext
: public ContextHandler2
694 PolarAdjustHandleContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, AdjustHandle
& rAdjustHandle
);
695 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
698 AdjustHandle
& mrAdjustHandle
;
699 CustomShapeProperties
& mrCustomShapeProperties
;
702 PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, AdjustHandle
& rAdjustHandle
)
703 : ContextHandler2( rParent
)
704 , mrAdjustHandle( rAdjustHandle
)
705 , mrCustomShapeProperties( rCustomShapeProperties
)
707 if ( rAttribs
.hasAttribute( XML_gdRefR
) )
709 mrAdjustHandle
.polar
= true ;
710 mrAdjustHandle
.gdRef1
= GetGeomGuideName( rAttribs
.getString( XML_gdRefR
, "" ) );
712 if ( rAttribs
.hasAttribute( XML_minR
) )
714 mrAdjustHandle
.min1
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_minR
, "" ) );
716 if ( rAttribs
.hasAttribute( XML_maxR
) )
718 mrAdjustHandle
.max1
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_maxR
, "" ) );
720 if ( rAttribs
.hasAttribute( XML_gdRefAng
) )
722 mrAdjustHandle
.polar
= true ;
723 mrAdjustHandle
.gdRef2
= GetGeomGuideName( rAttribs
.getString( XML_gdRefAng
, "" ) );
725 if ( rAttribs
.hasAttribute( XML_minAng
) )
727 mrAdjustHandle
.min2
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_minAng
, "" ) );
729 if ( rAttribs
.hasAttribute( XML_maxAng
) )
731 mrAdjustHandle
.max2
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_maxAng
, "" ) );
735 ContextHandlerRef
PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
737 // mrAdjustHandle.pos uses planar coordinates.
738 if ( aElementToken
== A_TOKEN( pos
) )
739 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjustHandle
.pos
); // CT_AdjPoint2D
743 // CT_AdjustHandleList
744 class AdjustHandleListContext
: public ContextHandler2
747 AdjustHandleListContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< AdjustHandle
>& rAdjustHandleList
);
748 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
751 std::vector
< AdjustHandle
>& mrAdjustHandleList
;
752 CustomShapeProperties
& mrCustomShapeProperties
;
755 AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< AdjustHandle
>& rAdjustHandleList
)
756 : ContextHandler2( rParent
)
757 , mrAdjustHandleList( rAdjustHandleList
)
758 , mrCustomShapeProperties( rCustomShapeProperties
)
762 ContextHandlerRef
AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
764 if ( aElementToken
== A_TOKEN( ahXY
) ) // CT_XYAdjustHandle
766 AdjustHandle
aAdjustHandle( false );
767 mrAdjustHandleList
.push_back( aAdjustHandle
);
768 return new XYAdjustHandleContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjustHandleList
.back() );
770 else if ( aElementToken
== A_TOKEN( ahPolar
) ) // CT_PolarAdjustHandle
772 AdjustHandle
aAdjustHandle( true );
773 mrAdjustHandleList
.push_back( aAdjustHandle
);
774 return new PolarAdjustHandleContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjustHandleList
.back() );
780 class ConnectionSiteContext
: public ContextHandler2
783 ConnectionSiteContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, ConnectionSite
& rConnectionSite
);
784 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
787 ConnectionSite
& mrConnectionSite
;
788 CustomShapeProperties
& mrCustomShapeProperties
;
791 ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, ConnectionSite
& rConnectionSite
)
792 : ContextHandler2( rParent
)
793 , mrConnectionSite( rConnectionSite
)
794 , mrCustomShapeProperties( rCustomShapeProperties
)
796 mrConnectionSite
.ang
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_ang
).get() );
799 ContextHandlerRef
ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
801 if ( aElementToken
== A_TOKEN( pos
) )
802 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrConnectionSite
.pos
); // CT_AdjPoint2D
807 class Path2DMoveToContext
: public ContextHandler2
810 Path2DMoveToContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
);
811 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
814 EnhancedCustomShapeParameterPair
& mrAdjPoint2D
;
815 CustomShapeProperties
& mrCustomShapeProperties
;
818 Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
)
819 : ContextHandler2( rParent
)
820 , mrAdjPoint2D( rAdjPoint2D
)
821 , mrCustomShapeProperties( rCustomShapeProperties
)
825 ContextHandlerRef
Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
827 if ( aElementToken
== A_TOKEN( pt
) )
828 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjPoint2D
); // CT_AdjPoint2D
833 class Path2DLineToContext
: public ContextHandler2
836 Path2DLineToContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
);
837 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
840 EnhancedCustomShapeParameterPair
& mrAdjPoint2D
;
841 CustomShapeProperties
& mrCustomShapeProperties
;
844 Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
)
845 : ContextHandler2( rParent
)
846 , mrAdjPoint2D( rAdjPoint2D
)
847 , mrCustomShapeProperties( rCustomShapeProperties
)
851 ContextHandlerRef
Path2DLineToContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
853 if ( aElementToken
== A_TOKEN( pt
) )
854 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjPoint2D
); // CT_AdjPoint2D
858 // CT_Path2DQuadBezierTo
859 class Path2DQuadBezierToContext
: public ContextHandler2
862 Path2DQuadBezierToContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rPt1
, EnhancedCustomShapeParameterPair
& rPt2
);
863 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
866 EnhancedCustomShapeParameterPair
& mrPt1
;
867 EnhancedCustomShapeParameterPair
& mrPt2
;
869 CustomShapeProperties
& mrCustomShapeProperties
;
872 Path2DQuadBezierToContext::Path2DQuadBezierToContext( ContextHandler2Helper
const & rParent
,
873 CustomShapeProperties
& rCustomShapeProperties
,
874 EnhancedCustomShapeParameterPair
& rPt1
,
875 EnhancedCustomShapeParameterPair
& rPt2
)
876 : ContextHandler2( rParent
)
880 , mrCustomShapeProperties( rCustomShapeProperties
)
884 ContextHandlerRef
Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
886 if ( aElementToken
== A_TOKEN( pt
) )
887 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, nCount
++ ? mrPt2
: mrPt1
); // CT_AdjPoint2D
891 // CT_Path2DCubicBezierTo
892 class Path2DCubicBezierToContext
: public ContextHandler2
895 Path2DCubicBezierToContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
,
896 EnhancedCustomShapeParameterPair
&, EnhancedCustomShapeParameterPair
&, EnhancedCustomShapeParameterPair
& );
897 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
900 CustomShapeProperties
& mrCustomShapeProperties
;
901 EnhancedCustomShapeParameterPair
& mrControlPt1
;
902 EnhancedCustomShapeParameterPair
& mrControlPt2
;
903 EnhancedCustomShapeParameterPair
& mrEndPt
;
907 Path2DCubicBezierToContext::Path2DCubicBezierToContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
,
908 EnhancedCustomShapeParameterPair
& rControlPt1
,
909 EnhancedCustomShapeParameterPair
& rControlPt2
,
910 EnhancedCustomShapeParameterPair
& rEndPt
)
911 : ContextHandler2( rParent
)
912 , mrCustomShapeProperties( rCustomShapeProperties
)
913 , mrControlPt1( rControlPt1
)
914 , mrControlPt2( rControlPt2
)
920 ContextHandlerRef
Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
922 if ( aElementToken
== A_TOKEN( pt
) )
923 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
,
924 nCount
++ ? nCount
== 2 ? mrControlPt2
: mrEndPt
: mrControlPt1
); // CT_AdjPoint2D
929 class Path2DContext
: public ContextHandler2
932 Path2DContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< css::drawing::EnhancedCustomShapeSegment
>& rSegments
, Path2D
& rPath2D
);
933 virtual void onEndElement() override
;
934 virtual ::oox::core::ContextHandlerRef
935 onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
939 std::vector
< css::drawing::EnhancedCustomShapeSegment
>& mrSegments
;
940 CustomShapeProperties
& mrCustomShapeProperties
;
943 Path2DContext::Path2DContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< css::drawing::EnhancedCustomShapeSegment
>& rSegments
, Path2D
& rPath2D
)
944 : ContextHandler2( rParent
)
945 , mrPath2D( rPath2D
)
946 , mrSegments( rSegments
)
947 , mrCustomShapeProperties( rCustomShapeProperties
)
949 rPath2D
.w
= rAttribs
.getString( XML_w
, "" ).toInt64();
950 rPath2D
.h
= rAttribs
.getString( XML_h
, "" ).toInt64();
951 rPath2D
.fill
= rAttribs
.getToken( XML_fill
, XML_norm
);
952 rPath2D
.stroke
= rAttribs
.getBool( XML_stroke
, true );
953 rPath2D
.extrusionOk
= rAttribs
.getBool( XML_extrusionOk
, true );
956 void Path2DContext::onEndElement()
958 EnhancedCustomShapeSegment aNewSegment
;
959 switch ( mrPath2D
.fill
)
962 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::NOFILL
;
965 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::DARKEN
;
968 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::DARKENLESS
;
971 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::LIGHTEN
;
973 case XML_lightenLess
:
974 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::LIGHTENLESS
;
977 if (mrPath2D
.fill
!= XML_norm
) {
978 aNewSegment
.Count
= 0;
979 mrSegments
.push_back( aNewSegment
);
981 if ( !mrPath2D
.stroke
)
983 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::NOSTROKE
;
984 aNewSegment
.Count
= 0;
985 mrSegments
.push_back( aNewSegment
);
987 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::ENDSUBPATH
;
988 aNewSegment
.Count
= 0;
989 mrSegments
.push_back( aNewSegment
);
993 ContextHandlerRef
Path2DContext::onCreateContext( sal_Int32 aElementToken
,
994 const AttributeList
& rAttribs
)
996 switch( aElementToken
)
998 case A_TOKEN( close
) :
1000 // ignore close after move to (ppt does seems to do the same, see accentCallout2 preset for example)
1001 if ( mrSegments
.empty() || ( mrSegments
.back().Command
!= EnhancedCustomShapeSegmentCommand::MOVETO
) ) {
1002 EnhancedCustomShapeSegment aNewSegment
;
1003 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
;
1004 aNewSegment
.Count
= 0;
1005 mrSegments
.push_back( aNewSegment
);
1009 case A_TOKEN( moveTo
) :
1011 EnhancedCustomShapeSegment aNewSegment
;
1012 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::MOVETO
;
1013 aNewSegment
.Count
= 1;
1014 mrSegments
.push_back( aNewSegment
);
1016 EnhancedCustomShapeParameterPair aAdjPoint2D
;
1017 mrPath2D
.parameter
.push_back( aAdjPoint2D
);
1018 return new Path2DMoveToContext( *this, mrCustomShapeProperties
, mrPath2D
.parameter
.back() );
1021 case A_TOKEN( lnTo
) :
1023 if ( !mrSegments
.empty() && ( mrSegments
.back().Command
== EnhancedCustomShapeSegmentCommand::LINETO
) )
1024 mrSegments
.back().Count
++;
1027 EnhancedCustomShapeSegment aSegment
;
1028 aSegment
.Command
= EnhancedCustomShapeSegmentCommand::LINETO
;
1030 mrSegments
.push_back( aSegment
);
1032 EnhancedCustomShapeParameterPair aAdjPoint2D
;
1033 mrPath2D
.parameter
.push_back( aAdjPoint2D
);
1034 return new Path2DLineToContext( *this, mrCustomShapeProperties
, mrPath2D
.parameter
.back() );
1037 case A_TOKEN( arcTo
) : // CT_Path2DArcTo
1039 if ( !mrSegments
.empty() && ( mrSegments
.back().Command
== EnhancedCustomShapeSegmentCommand::ARCANGLETO
) )
1040 mrSegments
.back().Count
++;
1043 EnhancedCustomShapeSegment aSegment
;
1044 aSegment
.Command
= EnhancedCustomShapeSegmentCommand::ARCANGLETO
;
1046 mrSegments
.push_back( aSegment
);
1049 EnhancedCustomShapeParameterPair aScale
;
1050 EnhancedCustomShapeParameterPair aAngles
;
1052 aScale
.First
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_wR
).get() );
1053 aScale
.Second
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_hR
).get() );
1055 CustomShapeGuide aGuide
;
1056 sal_Int32 nArcNum
= mrCustomShapeProperties
.getArcNum();
1059 aGuide
.maName
= "arctosa" + OUString::number( nArcNum
);
1060 aGuide
.maFormula
= "("
1061 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_stAng
).get() ) )
1063 aAngles
.First
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties
.getGuideList(), aGuide
);
1064 aAngles
.First
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
1067 aGuide
.maName
= "arctosw" + OUString::number( nArcNum
);
1068 aGuide
.maFormula
= "("
1069 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_swAng
).get() ) )
1071 aAngles
.Second
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties
.getGuideList(), aGuide
);
1072 aAngles
.Second
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
1074 mrPath2D
.parameter
.push_back( aScale
);
1075 mrPath2D
.parameter
.push_back( aAngles
);
1078 case A_TOKEN( quadBezTo
) :
1080 if ( !mrSegments
.empty() && ( mrSegments
.back().Command
== EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO
) )
1081 mrSegments
.back().Count
++;
1084 EnhancedCustomShapeSegment aSegment
;
1085 aSegment
.Command
= EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO
;
1087 mrSegments
.push_back( aSegment
);
1089 EnhancedCustomShapeParameterPair aPt1
;
1090 EnhancedCustomShapeParameterPair aPt2
;
1091 mrPath2D
.parameter
.push_back( aPt1
);
1092 mrPath2D
.parameter
.push_back( aPt2
);
1093 return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties
,
1094 mrPath2D
.parameter
[ mrPath2D
.parameter
.size() - 2 ],
1095 mrPath2D
.parameter
.back() );
1098 case A_TOKEN( cubicBezTo
) :
1100 if ( !mrSegments
.empty() && ( mrSegments
.back().Command
== EnhancedCustomShapeSegmentCommand::CURVETO
) )
1101 mrSegments
.back().Count
++;
1104 EnhancedCustomShapeSegment aSegment
;
1105 aSegment
.Command
= EnhancedCustomShapeSegmentCommand::CURVETO
;
1107 mrSegments
.push_back( aSegment
);
1109 EnhancedCustomShapeParameterPair aControlPt1
;
1110 EnhancedCustomShapeParameterPair aControlPt2
;
1111 EnhancedCustomShapeParameterPair aEndPt
;
1112 mrPath2D
.parameter
.push_back( aControlPt1
);
1113 mrPath2D
.parameter
.push_back( aControlPt2
);
1114 mrPath2D
.parameter
.push_back( aEndPt
);
1115 return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties
,
1116 mrPath2D
.parameter
[ mrPath2D
.parameter
.size() - 3 ],
1117 mrPath2D
.parameter
[ mrPath2D
.parameter
.size() - 2 ],
1118 mrPath2D
.parameter
.back() );
1126 class Path2DListContext
: public ContextHandler2
1129 Path2DListContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< EnhancedCustomShapeSegment
>& rSegments
,
1130 std::vector
< Path2D
>& rPath2DList
);
1132 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
1136 CustomShapeProperties
& mrCustomShapeProperties
;
1137 std::vector
< css::drawing::EnhancedCustomShapeSegment
>& mrSegments
;
1138 std::vector
< Path2D
>& mrPath2DList
;
1141 Path2DListContext:: Path2DListContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< EnhancedCustomShapeSegment
>& rSegments
,
1142 std::vector
< Path2D
>& rPath2DList
)
1143 : ContextHandler2( rParent
)
1144 , mrCustomShapeProperties( rCustomShapeProperties
)
1145 , mrSegments( rSegments
)
1146 , mrPath2DList( rPath2DList
)
1150 ContextHandlerRef
Path2DListContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
1152 if ( aElementToken
== A_TOKEN( path
) )
1155 mrPath2DList
.push_back( aPath2D
);
1156 return new Path2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrSegments
, mrPath2DList
.back() );
1161 // CT_CustomGeometry2D
1162 CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper
const & rParent
, CustomShapeProperties
& rCustomShapeProperties
)
1163 : ContextHandler2( rParent
)
1164 , mrCustomShapeProperties( rCustomShapeProperties
)
1168 ContextHandlerRef
CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
1170 switch( aElementToken
)
1172 case A_TOKEN( avLst
): // CT_GeomGuideList adjust value list
1173 return new GeomGuideListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getAdjustmentGuideList() );
1174 case A_TOKEN( gdLst
): // CT_GeomGuideList guide list
1175 return new GeomGuideListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getGuideList() );
1176 case A_TOKEN( ahLst
): // CT_AdjustHandleList adjust handle list
1177 return new AdjustHandleListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getAdjustHandleList() );
1178 case A_TOKEN( cxnLst
): // CT_ConnectionSiteList connection site list
1180 case A_TOKEN( rect
): // CT_GeomRectList geometry rect list
1183 aGeomRect
.l
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_l
).get() );
1184 aGeomRect
.t
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_t
).get() );
1185 aGeomRect
.r
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_r
).get() );
1186 aGeomRect
.b
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_b
).get() );
1187 mrCustomShapeProperties
.getTextRect() = aGeomRect
;
1190 case A_TOKEN( pathLst
): // CT_Path2DList 2d path list
1191 return new Path2DListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getSegments(), mrCustomShapeProperties
.getPath2DList() );
1194 case A_TOKEN( cxn
): // CT_ConnectionSite
1196 ConnectionSite aConnectionSite
;
1197 mrCustomShapeProperties
.getConnectionSiteList().push_back( aConnectionSite
);
1198 return new ConnectionSiteContext( *this, rAttribs
, mrCustomShapeProperties
, mrCustomShapeProperties
.getConnectionSiteList().back() );
1204 // CT_PresetGeometry2D
1205 PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
)
1206 : ContextHandler2( rParent
)
1207 , mrCustomShapeProperties( rCustomShapeProperties
)
1209 sal_Int32 nShapeType
= rAttribs
.getToken( XML_prst
, FastToken::DONTKNOW
);
1210 OSL_ENSURE( nShapeType
!= FastToken::DONTKNOW
, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1211 mrCustomShapeProperties
.setShapePresetType( nShapeType
);
1214 ContextHandlerRef
PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& )
1216 if ( aElementToken
== A_TOKEN( avLst
) )
1217 return new GeomGuideListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getAdjustmentGuideList() );
1222 // CT_PresetTextShape
1223 PresetTextShapeContext::PresetTextShapeContext( ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
)
1224 : ContextHandler2( rParent
)
1225 , mrCustomShapeProperties( rCustomShapeProperties
)
1227 sal_Int32 nShapeType
= rAttribs
.getToken( XML_prst
, FastToken::DONTKNOW
);
1228 OSL_ENSURE( nShapeType
!= FastToken::DONTKNOW
, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1229 mrCustomShapeProperties
.setShapePresetType( nShapeType
);
1232 ContextHandlerRef
PresetTextShapeContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& )
1234 if ( aElementToken
== A_TOKEN( avLst
) )
1235 return new GeomGuideListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getAdjustmentGuideList() );
1242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */