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 "oox/helper/helper.hxx"
28 #include "oox/helper/attributelist.hxx"
29 #include "oox/helper/propertymap.hxx"
30 #include <oox/token/namespaces.hxx>
31 #include <oox/token/tokens.hxx>
32 #include <unordered_map>
34 using namespace ::oox::core
;
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::drawing
;
37 using namespace ::com::sun::star::xml::sax
;
39 namespace oox
{ namespace drawingml
{
62 struct FormularCommandNameTable
67 static const FormularCommandNameTable pFormularCommandNameTable
[] =
70 { "+-", FC_PLUSMINUS
},
72 { "ifelse", FC_IFELSE
},
89 typedef std::unordered_map
< OUString
, FormularCommand
, OUStringHash
> FormulaCommandHMap
;
91 static const FormulaCommandHMap
* pCommandHashMap
;
93 OUString
GetFormulaParameter( const EnhancedCustomShapeParameter
& rParameter
)
96 switch( rParameter
.Type
)
98 case EnhancedCustomShapeParameterType::NORMAL
:
100 if ( rParameter
.Value
.getValueTypeClass() == TypeClass_DOUBLE
)
103 if ( rParameter
.Value
>>= fValue
)
104 aRet
= OUString::number( fValue
);
108 sal_Int32 nValue
= 0;
109 if ( rParameter
.Value
>>= nValue
)
110 aRet
= OUString::number( nValue
);
114 case EnhancedCustomShapeParameterType::EQUATION
:
116 if ( rParameter
.Value
.getValueTypeClass() == TypeClass_LONG
)
118 sal_Int32 nFormulaIndex
;
119 if ( rParameter
.Value
>>= nFormulaIndex
)
122 + OUString::number( nFormulaIndex
)
128 // ups... we should have an index here and not the formula name
132 case EnhancedCustomShapeParameterType::ADJUSTMENT
:
134 if ( rParameter
.Value
.getValueTypeClass() == TypeClass_LONG
)
136 sal_Int32 nAdjustmentIndex
;
137 if ( rParameter
.Value
>>= nAdjustmentIndex
)
140 + OUString::number( nAdjustmentIndex
)
146 // ups... we should have an index here and not the formula name
150 case EnhancedCustomShapeParameterType::LEFT
:
153 case EnhancedCustomShapeParameterType::TOP
:
156 case EnhancedCustomShapeParameterType::RIGHT
:
159 case EnhancedCustomShapeParameterType::BOTTOM
:
162 case EnhancedCustomShapeParameterType::XSTRETCH
:
165 case EnhancedCustomShapeParameterType::YSTRETCH
:
168 case EnhancedCustomShapeParameterType::HASSTROKE
:
171 case EnhancedCustomShapeParameterType::HASFILL
:
174 case EnhancedCustomShapeParameterType::WIDTH
:
177 case EnhancedCustomShapeParameterType::HEIGHT
:
180 case EnhancedCustomShapeParameterType::LOGWIDTH
:
183 case EnhancedCustomShapeParameterType::LOGHEIGHT
:
190 static EnhancedCustomShapeParameter
GetAdjCoordinate( CustomShapeProperties
& rCustomShapeProperties
, const OUString
& rValue
, bool bNoSymbols
= true )
192 css::drawing::EnhancedCustomShapeParameter aRet
;
193 if ( !rValue
.isEmpty() )
195 bool bConstant
= true;
196 sal_Int32 nConstant
= -1;
197 sal_Int32 nIntVal
= 0;
199 // first check if it's a constant value
200 switch( AttributeConversion::decodeToken( rValue
) )
202 case XML_3cd4
: nConstant
= 270 * 60000; break;
203 case XML_3cd8
: nConstant
= 135 * 60000; break;
204 case XML_5cd8
: nConstant
= 225 * 60000; break;
205 case XML_7cd8
: nConstant
= 315 * 60000; break;
206 case XML_cd2
: nConstant
= 180 * 60000; break;
207 case XML_cd3
: nConstant
= 120 * 60000; break;
208 case XML_cd4
: nConstant
= 90 * 60000; break;
209 case XML_cd8
: nConstant
= 45 * 60000; break;
211 case XML_b
: // variable height of the shape defined in spPr
216 CustomShapeGuide aGuide
;
217 aGuide
.maName
= rValue
;
218 aGuide
.maFormula
= "logheight" ;
220 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
221 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
224 aRet
.Type
= EnhancedCustomShapeParameterType::LOGHEIGHT
; // TODO: HEIGHT needs to be implemented
229 nIntVal
+= 2; // */ h 1.0 10.0
231 case XML_hd8
: // */ h 1.0 8.0
234 case XML_hd6
: // */ h 1.0 6.0
237 case XML_hd5
: // */ h 1.0 5.0
240 case XML_hd4
: // */ h 1.0 4.0
243 case XML_hd3
: // */ h 1.0 3.0
246 case XML_hd2
: // */ h 1.0 2.0
247 case XML_vc
: // */ h 1.0 2.0
251 CustomShapeGuide aGuide
;
252 aGuide
.maName
= rValue
;
253 aGuide
.maFormula
= "logheight/" + OUString::number( nIntVal
);
255 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
256 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
264 aRet
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
268 case XML_ls
: // longest side: max w h
270 CustomShapeGuide aGuide
;
271 aGuide
.maName
= rValue
;
272 aGuide
.maFormula
= "max(logwidth,logheight)";
274 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
275 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
278 case XML_ss
: // shortest side: min w h
280 CustomShapeGuide aGuide
;
281 aGuide
.maName
= rValue
;
282 aGuide
.maFormula
= "min(logwidth,logheight)";
284 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
285 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
288 case XML_ssd32
: // */ ss 1.0 32.0
291 case XML_ssd16
: // */ ss 1.0 16.0
294 case XML_ssd8
: // */ ss 1.0 8.0
297 case XML_ssd6
: // */ ss 1.0 6.0
300 case XML_ssd4
: // */ ss 1.0 4.0
303 case XML_ssd2
: // */ ss 1.0 2.0
307 CustomShapeGuide aGuide
;
308 aGuide
.maName
= rValue
;
309 aGuide
.maFormula
= "min(logwidth,logheight)/" + OUString::number( nIntVal
);
311 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
312 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
316 case XML_r
: // variable width of the shape defined in spPr
321 CustomShapeGuide aGuide
;
322 aGuide
.maName
= rValue
;
323 aGuide
.maFormula
= "logwidth" ;
325 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
326 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
329 aRet
.Type
= EnhancedCustomShapeParameterType::LOGWIDTH
;
333 case XML_wd32
: // */ w 1.0 32.0
336 case XML_wd12
: // */ w 1.0 12.0
339 case XML_wd10
: // */ w 1.0 10.0
342 case XML_wd8
: // */ w 1.0 8.0
345 case XML_wd6
: // */ w 1.0 6.0
348 case XML_wd5
: // */ w 1.0 5.0
351 case XML_wd4
: // */ w 1.0 4.0
354 case XML_wd3
: // */ w 1.0 3.0
357 case XML_hc
: // */ w 1.0 2.0
358 case XML_wd2
: // */ w 1.0 2.0
362 CustomShapeGuide aGuide
;
363 aGuide
.maName
= rValue
;
364 aGuide
.maFormula
= "logwidth/" + OUString::number( nIntVal
);
366 aRet
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), aGuide
);
367 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
377 if (nConstant
!= -1) {
378 aRet
.Value
<<= nConstant
;
379 aRet
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
384 sal_Unicode n
= rValue
[ 0 ];
385 if ( ( n
== '+' ) || ( n
== '-' ) )
387 if ( rValue
.getLength() > 1 )
390 if ( ( n
>= '0' ) && ( n
<= '9' ) )
391 { // seems to be a ST_Coordinate
392 aRet
.Value
<<= rValue
.toInt32();
393 aRet
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
397 sal_Int32 nGuideIndex
= CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties
.getAdjustmentGuideList(), rValue
);
398 if ( nGuideIndex
>= 0 )
400 aRet
.Value
<<= nGuideIndex
;
401 aRet
.Type
= EnhancedCustomShapeParameterType::ADJUSTMENT
;
405 nGuideIndex
= CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties
.getGuideList(), rValue
);
406 if ( nGuideIndex
>= 0 )
408 aRet
.Value
<<= nGuideIndex
;
409 aRet
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
413 SAL_WARN("oox", "error: unhandled value " << rValue
);
414 aRet
.Value
<<= rValue
;
424 class GeomGuideListContext
: public ContextHandler2
427 GeomGuideListContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< CustomShapeGuide
>& rGuideList
);
428 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
431 std::vector
< CustomShapeGuide
>& mrGuideList
;
432 CustomShapeProperties
& mrCustomShapeProperties
;
435 GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< CustomShapeGuide
>& rGuideList
)
436 : ContextHandler2( rParent
)
437 , mrGuideList( rGuideList
)
438 , mrCustomShapeProperties( rCustomShapeProperties
)
442 static OUString
convertToOOEquation( CustomShapeProperties
& rCustomShapeProperties
, const OUString
& rSource
)
444 if ( !pCommandHashMap
)
446 FormulaCommandHMap
* pHM
= new FormulaCommandHMap
;
447 for(const FormularCommandNameTable
& i
: pFormularCommandNameTable
)
448 (*pHM
)[ OUString::createFromAscii( i
.pS
) ] = i
.pE
;
449 pCommandHashMap
= pHM
;
452 std::vector
< OUString
> aTokens
;
453 sal_Int32 nIndex
= 0;
456 OUString
aToken( rSource
.getToken( 0, ' ', nIndex
) );
457 if ( !aToken
.isEmpty() )
458 aTokens
.push_back( aToken
);
460 while ( nIndex
>= 0 );
463 if ( !aTokens
.empty() )
465 sal_Int32 i
, nParameters
= aTokens
.size() - 1;
466 if ( nParameters
> 3 )
469 OUString sParameters
[ 3 ];
471 for ( i
= 0; i
< nParameters
; i
++ )
472 sParameters
[ i
] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties
, aTokens
[ i
+ 1 ], false ) );
474 const FormulaCommandHMap::const_iterator
aIter( pCommandHashMap
->find( aTokens
[ 0 ] ) );
475 if ( aIter
!= pCommandHashMap
->end() )
477 switch( aIter
->second
)
481 if ( nParameters
== 3 )
482 aEquation
= sParameters
[ 0 ] + "*" + sParameters
[ 1 ]
483 + "/" + sParameters
[ 2 ];
488 if ( nParameters
== 3 )
489 aEquation
= sParameters
[ 0 ] + "+" + sParameters
[ 1 ]
490 + "-" + sParameters
[ 2 ];
495 if ( nParameters
== 3 )
496 aEquation
= "(" + sParameters
[ 0 ] + "+"
497 + sParameters
[ 1 ] + ")/" + sParameters
[ 2 ];
503 if ( nParameters
== 3 )
504 aEquation
= "if(" + sParameters
[ 0 ] + ","
505 + sParameters
[ 1 ] + "," + sParameters
[ 2 ] + ")";
510 if ( nParameters
== 1 )
511 aEquation
= "abs(" + sParameters
[ 0 ] + ")";
516 if ( nParameters
== 2 )
517 aEquation
= "(10800000*atan2(" + sParameters
[ 1 ] + ","
518 + sParameters
[ 0 ] + "))/pi";
523 if ( nParameters
== 3 )
524 aEquation
= sParameters
[ 0 ] + "*(cos(atan2(" +
525 sParameters
[ 2 ] + "," + sParameters
[ 1 ] + ")))";
530 if ( nParameters
== 2 )
531 aEquation
= sParameters
[ 0 ] + "*cos(pi*(" +
532 sParameters
[ 1 ] + ")/10800000)";
537 if ( nParameters
== 2 )
538 aEquation
= "max(" + sParameters
[ 0 ] + "," +
539 sParameters
[ 1 ] + ")";
544 if ( nParameters
== 2 )
545 aEquation
= "min(" + sParameters
[ 0 ] + "," +
546 sParameters
[ 1 ] + ")";
551 if ( nParameters
== 3 )
553 + sParameters
[ 0 ] + "*" + sParameters
[ 0 ] + "+"
554 + sParameters
[ 1 ] + "*" + sParameters
[ 1 ] + "+"
555 + sParameters
[ 2 ] + "*" + sParameters
[ 2 ] + ")";
560 if ( nParameters
== 3 ) // if(x-y,x,if(y-z,z,y))
561 aEquation
= "if(" + sParameters
[ 0 ] + "-" + sParameters
[ 1 ]
562 + "," + sParameters
[ 0 ] + ",if(" + sParameters
[ 2 ]
563 + "-" + sParameters
[ 1 ] + "," + sParameters
[ 1 ]
564 + "," + sParameters
[ 2 ] + "))";
569 if ( nParameters
== 3 )
570 aEquation
= sParameters
[ 0 ] + "*(sin(atan2(" +
571 sParameters
[ 2 ] + "," + sParameters
[ 1 ] + ")))";
576 if ( nParameters
== 2 )
577 aEquation
= sParameters
[ 0 ] + "*sin(pi*(" +
578 sParameters
[ 1 ] + ")/10800000)";
583 if ( nParameters
== 1 )
584 aEquation
= "sqrt(" + sParameters
[ 0 ] + ")";
589 if ( nParameters
== 2 )
590 aEquation
= sParameters
[ 0 ] + "*tan(pi*(" +
591 sParameters
[ 1 ] + ")/10800000)";
596 if ( nParameters
== 1 )
597 aEquation
= sParameters
[ 0 ];
608 ContextHandlerRef
GeomGuideListContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
610 if ( aElementToken
== A_TOKEN( gd
) ) // CT_GeomGuide
612 CustomShapeGuide aGuide
;
613 aGuide
.maName
= rAttribs
.getString( XML_name
).get();
614 aGuide
.maFormula
= convertToOOEquation( mrCustomShapeProperties
, rAttribs
.getString( XML_fmla
).get() );
615 mrGuideList
.push_back( aGuide
);
620 static const OUString
& GetGeomGuideName( const OUString
& rValue
)
626 class AdjPoint2DContext
: public ContextHandler2
629 AdjPoint2DContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
);
632 AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
)
633 : ContextHandler2( rParent
)
635 rAdjPoint2D
.First
= GetAdjCoordinate( rCustomShapeProperties
, rAttribs
.getString( XML_x
).get() );
636 rAdjPoint2D
.Second
= GetAdjCoordinate( rCustomShapeProperties
, rAttribs
.getString( XML_y
).get() );
640 class XYAdjustHandleContext
: public ContextHandler2
643 XYAdjustHandleContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, AdjustHandle
& rAdjustHandle
);
644 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
647 AdjustHandle
& mrAdjustHandle
;
648 CustomShapeProperties
& mrCustomShapeProperties
;
651 XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, AdjustHandle
& rAdjustHandle
)
652 : ContextHandler2( rParent
)
653 , mrAdjustHandle( rAdjustHandle
)
654 , mrCustomShapeProperties( rCustomShapeProperties
)
656 if ( rAttribs
.hasAttribute( XML_gdRefX
) )
658 mrAdjustHandle
.gdRef1
= GetGeomGuideName( rAttribs
.getString( XML_gdRefX
, "" ) );
660 if ( rAttribs
.hasAttribute( XML_minX
) )
662 mrAdjustHandle
.min1
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_minX
, "" ) );
664 if ( rAttribs
.hasAttribute( XML_maxX
) )
666 mrAdjustHandle
.max1
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_maxX
, "" ) );
668 if ( rAttribs
.hasAttribute( XML_gdRefY
) )
670 mrAdjustHandle
.gdRef2
= GetGeomGuideName( rAttribs
.getString( XML_gdRefY
, "" ) );
672 if ( rAttribs
.hasAttribute( XML_minY
) )
674 mrAdjustHandle
.min2
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_minY
, "" ) );
676 if ( rAttribs
.hasAttribute( XML_maxY
) )
678 mrAdjustHandle
.max2
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_maxY
, "" ) );
682 ContextHandlerRef
XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
684 if ( aElementToken
== A_TOKEN( pos
) )
685 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjustHandle
.pos
); // CT_AdjPoint2D
689 // CT_PolarAdjustHandle
690 class PolarAdjustHandleContext
: public ContextHandler2
693 PolarAdjustHandleContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, AdjustHandle
& rAdjustHandle
);
694 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
697 AdjustHandle
& mrAdjustHandle
;
698 CustomShapeProperties
& mrCustomShapeProperties
;
701 PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, AdjustHandle
& rAdjustHandle
)
702 : ContextHandler2( rParent
)
703 , mrAdjustHandle( rAdjustHandle
)
704 , mrCustomShapeProperties( rCustomShapeProperties
)
706 if ( rAttribs
.hasAttribute( XML_gdRefR
) )
708 mrAdjustHandle
.polar
= true ;
709 mrAdjustHandle
.gdRef1
= GetGeomGuideName( rAttribs
.getString( XML_gdRefR
, "" ) );
711 if ( rAttribs
.hasAttribute( XML_minR
) )
713 mrAdjustHandle
.min1
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_minR
, "" ) );
715 if ( rAttribs
.hasAttribute( XML_maxR
) )
717 mrAdjustHandle
.max1
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_maxR
, "" ) );
719 if ( rAttribs
.hasAttribute( XML_gdRefAng
) )
721 mrAdjustHandle
.polar
= true ;
722 mrAdjustHandle
.gdRef2
= GetGeomGuideName( rAttribs
.getString( XML_gdRefAng
, "" ) );
724 if ( rAttribs
.hasAttribute( XML_minAng
) )
726 mrAdjustHandle
.min2
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_minAng
, "" ) );
728 if ( rAttribs
.hasAttribute( XML_maxAng
) )
730 mrAdjustHandle
.max2
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_maxAng
, "" ) );
734 ContextHandlerRef
PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
736 // mrAdjustHandle.pos uses planar coordinates.
737 if ( aElementToken
== A_TOKEN( pos
) )
738 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjustHandle
.pos
); // CT_AdjPoint2D
742 // CT_AdjustHandleList
743 class AdjustHandleListContext
: public ContextHandler2
746 AdjustHandleListContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< AdjustHandle
>& rAdjustHandleList
);
747 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
750 std::vector
< AdjustHandle
>& mrAdjustHandleList
;
751 CustomShapeProperties
& mrCustomShapeProperties
;
754 AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< AdjustHandle
>& rAdjustHandleList
)
755 : ContextHandler2( rParent
)
756 , mrAdjustHandleList( rAdjustHandleList
)
757 , mrCustomShapeProperties( rCustomShapeProperties
)
761 ContextHandlerRef
AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
763 if ( aElementToken
== A_TOKEN( ahXY
) ) // CT_XYAdjustHandle
765 AdjustHandle
aAdjustHandle( false );
766 mrAdjustHandleList
.push_back( aAdjustHandle
);
767 return new XYAdjustHandleContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjustHandleList
.back() );
769 else if ( aElementToken
== A_TOKEN( ahPolar
) ) // CT_PolarAdjustHandle
771 AdjustHandle
aAdjustHandle( true );
772 mrAdjustHandleList
.push_back( aAdjustHandle
);
773 return new PolarAdjustHandleContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjustHandleList
.back() );
779 class ConnectionSiteContext
: public ContextHandler2
782 ConnectionSiteContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, ConnectionSite
& rConnectionSite
);
783 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
786 ConnectionSite
& mrConnectionSite
;
787 CustomShapeProperties
& mrCustomShapeProperties
;
790 ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, ConnectionSite
& rConnectionSite
)
791 : ContextHandler2( rParent
)
792 , mrConnectionSite( rConnectionSite
)
793 , mrCustomShapeProperties( rCustomShapeProperties
)
795 mrConnectionSite
.ang
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_ang
).get() );
798 ContextHandlerRef
ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
800 if ( aElementToken
== A_TOKEN( pos
) )
801 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrConnectionSite
.pos
); // CT_AdjPoint2D
806 class Path2DMoveToContext
: public ContextHandler2
809 Path2DMoveToContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
);
810 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
813 EnhancedCustomShapeParameterPair
& mrAdjPoint2D
;
814 CustomShapeProperties
& mrCustomShapeProperties
;
817 Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
)
818 : ContextHandler2( rParent
)
819 , mrAdjPoint2D( rAdjPoint2D
)
820 , mrCustomShapeProperties( rCustomShapeProperties
)
824 ContextHandlerRef
Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
826 if ( aElementToken
== A_TOKEN( pt
) )
827 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjPoint2D
); // CT_AdjPoint2D
832 class Path2DLineToContext
: public ContextHandler2
835 Path2DLineToContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
);
836 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
839 EnhancedCustomShapeParameterPair
& mrAdjPoint2D
;
840 CustomShapeProperties
& mrCustomShapeProperties
;
843 Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rAdjPoint2D
)
844 : ContextHandler2( rParent
)
845 , mrAdjPoint2D( rAdjPoint2D
)
846 , mrCustomShapeProperties( rCustomShapeProperties
)
850 ContextHandlerRef
Path2DLineToContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
852 if ( aElementToken
== A_TOKEN( pt
) )
853 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrAdjPoint2D
); // CT_AdjPoint2D
857 // CT_Path2DQuadBezierTo
858 class Path2DQuadBezierToContext
: public ContextHandler2
861 Path2DQuadBezierToContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, EnhancedCustomShapeParameterPair
& rPt1
, EnhancedCustomShapeParameterPair
& rPt2
);
862 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
865 EnhancedCustomShapeParameterPair
& mrPt1
;
866 EnhancedCustomShapeParameterPair
& mrPt2
;
868 CustomShapeProperties
& mrCustomShapeProperties
;
871 Path2DQuadBezierToContext::Path2DQuadBezierToContext( ContextHandler2Helper
& rParent
,
872 CustomShapeProperties
& rCustomShapeProperties
,
873 EnhancedCustomShapeParameterPair
& rPt1
,
874 EnhancedCustomShapeParameterPair
& rPt2
)
875 : ContextHandler2( rParent
)
879 , mrCustomShapeProperties( rCustomShapeProperties
)
883 ContextHandlerRef
Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
885 if ( aElementToken
== A_TOKEN( pt
) )
886 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
, nCount
++ ? mrPt2
: mrPt1
); // CT_AdjPoint2D
890 // CT_Path2DCubicBezierTo
891 class Path2DCubicBezierToContext
: public ContextHandler2
894 Path2DCubicBezierToContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
,
895 EnhancedCustomShapeParameterPair
&, EnhancedCustomShapeParameterPair
&, EnhancedCustomShapeParameterPair
& );
896 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
899 CustomShapeProperties
& mrCustomShapeProperties
;
900 EnhancedCustomShapeParameterPair
& mrControlPt1
;
901 EnhancedCustomShapeParameterPair
& mrControlPt2
;
902 EnhancedCustomShapeParameterPair
& mrEndPt
;
906 Path2DCubicBezierToContext::Path2DCubicBezierToContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
,
907 EnhancedCustomShapeParameterPair
& rControlPt1
,
908 EnhancedCustomShapeParameterPair
& rControlPt2
,
909 EnhancedCustomShapeParameterPair
& rEndPt
)
910 : ContextHandler2( rParent
)
911 , mrCustomShapeProperties( rCustomShapeProperties
)
912 , mrControlPt1( rControlPt1
)
913 , mrControlPt2( rControlPt2
)
919 ContextHandlerRef
Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
921 if ( aElementToken
== A_TOKEN( pt
) )
922 return new AdjPoint2DContext( *this, rAttribs
, mrCustomShapeProperties
,
923 nCount
++ ? nCount
== 2 ? mrControlPt2
: mrEndPt
: mrControlPt1
); // CT_AdjPoint2D
928 class Path2DContext
: public ContextHandler2
931 Path2DContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< css::drawing::EnhancedCustomShapeSegment
>& rSegments
, Path2D
& rPath2D
);
932 virtual ~Path2DContext() override
;
933 virtual ::oox::core::ContextHandlerRef
934 onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
938 std::vector
< css::drawing::EnhancedCustomShapeSegment
>& mrSegments
;
939 CustomShapeProperties
& mrCustomShapeProperties
;
942 Path2DContext::Path2DContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< css::drawing::EnhancedCustomShapeSegment
>& rSegments
, Path2D
& rPath2D
)
943 : ContextHandler2( rParent
)
944 , mrPath2D( rPath2D
)
945 , mrSegments( rSegments
)
946 , mrCustomShapeProperties( rCustomShapeProperties
)
948 rPath2D
.w
= rAttribs
.getString( XML_w
, "" ).toInt64();
949 rPath2D
.h
= rAttribs
.getString( XML_h
, "" ).toInt64();
950 rPath2D
.fill
= rAttribs
.getToken( XML_fill
, XML_norm
);
951 rPath2D
.stroke
= rAttribs
.getBool( XML_stroke
, true );
952 rPath2D
.extrusionOk
= rAttribs
.getBool( XML_extrusionOk
, true );
955 Path2DContext::~Path2DContext()
957 EnhancedCustomShapeSegment aNewSegment
;
958 switch ( mrPath2D
.fill
)
961 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::NOFILL
;
964 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::DARKEN
;
967 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::DARKENLESS
;
970 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::LIGHTEN
;
972 case XML_lightenLess
:
973 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::LIGHTENLESS
;
976 if (mrPath2D
.fill
!= XML_norm
) {
977 aNewSegment
.Count
= 0;
978 mrSegments
.push_back( aNewSegment
);
980 if ( !mrPath2D
.stroke
)
982 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::NOSTROKE
;
983 aNewSegment
.Count
= 0;
984 mrSegments
.push_back( aNewSegment
);
986 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::ENDSUBPATH
;
987 aNewSegment
.Count
= 0;
988 mrSegments
.push_back( aNewSegment
);
991 ContextHandlerRef
Path2DContext::onCreateContext( sal_Int32 aElementToken
,
992 const AttributeList
& rAttribs
)
994 switch( aElementToken
)
996 case A_TOKEN( close
) :
998 // ignore close after move to (ppt does seems to do the same, see accentCallout2 preset for example)
999 if ( mrSegments
.empty() || ( mrSegments
.back().Command
!= EnhancedCustomShapeSegmentCommand::MOVETO
) ) {
1000 EnhancedCustomShapeSegment aNewSegment
;
1001 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
;
1002 aNewSegment
.Count
= 0;
1003 mrSegments
.push_back( aNewSegment
);
1007 case A_TOKEN( moveTo
) :
1009 EnhancedCustomShapeSegment aNewSegment
;
1010 aNewSegment
.Command
= EnhancedCustomShapeSegmentCommand::MOVETO
;
1011 aNewSegment
.Count
= 1;
1012 mrSegments
.push_back( aNewSegment
);
1014 EnhancedCustomShapeParameterPair aAdjPoint2D
;
1015 mrPath2D
.parameter
.push_back( aAdjPoint2D
);
1016 return new Path2DMoveToContext( *this, mrCustomShapeProperties
, mrPath2D
.parameter
.back() );
1019 case A_TOKEN( lnTo
) :
1021 if ( !mrSegments
.empty() && ( mrSegments
.back().Command
== EnhancedCustomShapeSegmentCommand::LINETO
) )
1022 mrSegments
.back().Count
++;
1025 EnhancedCustomShapeSegment aSegment
;
1026 aSegment
.Command
= EnhancedCustomShapeSegmentCommand::LINETO
;
1028 mrSegments
.push_back( aSegment
);
1030 EnhancedCustomShapeParameterPair aAdjPoint2D
;
1031 mrPath2D
.parameter
.push_back( aAdjPoint2D
);
1032 return new Path2DLineToContext( *this, mrCustomShapeProperties
, mrPath2D
.parameter
.back() );
1035 case A_TOKEN( arcTo
) : // CT_Path2DArcTo
1037 if ( !mrSegments
.empty() && ( mrSegments
.back().Command
== EnhancedCustomShapeSegmentCommand::ARCANGLETO
) )
1038 mrSegments
.back().Count
++;
1041 EnhancedCustomShapeSegment aSegment
;
1042 aSegment
.Command
= EnhancedCustomShapeSegmentCommand::ARCANGLETO
;
1044 mrSegments
.push_back( aSegment
);
1047 EnhancedCustomShapeParameterPair aScale
;
1048 EnhancedCustomShapeParameterPair aAngles
;
1050 aScale
.First
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_wR
).get() );
1051 aScale
.Second
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_hR
).get() );
1053 CustomShapeGuide aGuide
;
1054 sal_Int32 nArcNum
= mrCustomShapeProperties
.getArcNum();
1057 aGuide
.maName
= "arctosa" + OUString::number( nArcNum
);
1058 aGuide
.maFormula
= "("
1059 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_stAng
).get() ) )
1061 aAngles
.First
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties
.getGuideList(), aGuide
);
1062 aAngles
.First
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
1065 aGuide
.maName
= "arctosw" + OUString::number( nArcNum
);
1066 aGuide
.maFormula
= "("
1067 + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_swAng
).get() ) )
1069 aAngles
.Second
.Value
<<= CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties
.getGuideList(), aGuide
);
1070 aAngles
.Second
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
1072 mrPath2D
.parameter
.push_back( aScale
);
1073 mrPath2D
.parameter
.push_back( aAngles
);
1076 case A_TOKEN( quadBezTo
) :
1078 if ( !mrSegments
.empty() && ( mrSegments
.back().Command
== EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO
) )
1079 mrSegments
.back().Count
++;
1082 EnhancedCustomShapeSegment aSegment
;
1083 aSegment
.Command
= EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO
;
1085 mrSegments
.push_back( aSegment
);
1087 EnhancedCustomShapeParameterPair aPt1
;
1088 EnhancedCustomShapeParameterPair aPt2
;
1089 mrPath2D
.parameter
.push_back( aPt1
);
1090 mrPath2D
.parameter
.push_back( aPt2
);
1091 return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties
,
1092 mrPath2D
.parameter
[ mrPath2D
.parameter
.size() - 2 ],
1093 mrPath2D
.parameter
.back() );
1096 case A_TOKEN( cubicBezTo
) :
1098 if ( !mrSegments
.empty() && ( mrSegments
.back().Command
== EnhancedCustomShapeSegmentCommand::CURVETO
) )
1099 mrSegments
.back().Count
++;
1102 EnhancedCustomShapeSegment aSegment
;
1103 aSegment
.Command
= EnhancedCustomShapeSegmentCommand::CURVETO
;
1105 mrSegments
.push_back( aSegment
);
1107 EnhancedCustomShapeParameterPair aControlPt1
;
1108 EnhancedCustomShapeParameterPair aControlPt2
;
1109 EnhancedCustomShapeParameterPair aEndPt
;
1110 mrPath2D
.parameter
.push_back( aControlPt1
);
1111 mrPath2D
.parameter
.push_back( aControlPt2
);
1112 mrPath2D
.parameter
.push_back( aEndPt
);
1113 return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties
,
1114 mrPath2D
.parameter
[ mrPath2D
.parameter
.size() - 3 ],
1115 mrPath2D
.parameter
[ mrPath2D
.parameter
.size() - 2 ],
1116 mrPath2D
.parameter
.back() );
1124 class Path2DListContext
: public ContextHandler2
1127 Path2DListContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< EnhancedCustomShapeSegment
>& rSegments
,
1128 std::vector
< Path2D
>& rPath2DList
);
1130 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const ::oox::AttributeList
& rAttribs
) override
;
1134 CustomShapeProperties
& mrCustomShapeProperties
;
1135 std::vector
< css::drawing::EnhancedCustomShapeSegment
>& mrSegments
;
1136 std::vector
< Path2D
>& mrPath2DList
;
1139 Path2DListContext::Path2DListContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
, std::vector
< EnhancedCustomShapeSegment
>& rSegments
,
1140 std::vector
< Path2D
>& rPath2DList
)
1141 : ContextHandler2( rParent
)
1142 , mrCustomShapeProperties( rCustomShapeProperties
)
1143 , mrSegments( rSegments
)
1144 , mrPath2DList( rPath2DList
)
1148 ContextHandlerRef
Path2DListContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
1150 if ( aElementToken
== A_TOKEN( path
) )
1153 mrPath2DList
.push_back( aPath2D
);
1154 return new Path2DContext( *this, rAttribs
, mrCustomShapeProperties
, mrSegments
, mrPath2DList
.back() );
1159 // CT_CustomGeometry2D
1160 CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper
& rParent
, CustomShapeProperties
& rCustomShapeProperties
)
1161 : ContextHandler2( rParent
)
1162 , mrCustomShapeProperties( rCustomShapeProperties
)
1166 ContextHandlerRef
CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
1168 switch( aElementToken
)
1170 case A_TOKEN( avLst
): // CT_GeomGuideList adjust value list
1171 return new GeomGuideListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getAdjustmentGuideList() );
1172 case A_TOKEN( gdLst
): // CT_GeomGuideList guide list
1173 return new GeomGuideListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getGuideList() );
1174 case A_TOKEN( ahLst
): // CT_AdjustHandleList adjust handle list
1175 return new AdjustHandleListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getAdjustHandleList() );
1176 case A_TOKEN( cxnLst
): // CT_ConnectionSiteList connection site list
1178 case A_TOKEN( rect
): // CT_GeomRectList geometry rect list
1181 aGeomRect
.l
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_l
).get() );
1182 aGeomRect
.t
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_t
).get() );
1183 aGeomRect
.r
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_r
).get() );
1184 aGeomRect
.b
= GetAdjCoordinate( mrCustomShapeProperties
, rAttribs
.getString( XML_b
).get() );
1185 mrCustomShapeProperties
.getTextRect() = aGeomRect
;
1188 case A_TOKEN( pathLst
): // CT_Path2DList 2d path list
1189 return new Path2DListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getSegments(), mrCustomShapeProperties
.getPath2DList() );
1192 case A_TOKEN( cxn
): // CT_ConnectionSite
1194 ConnectionSite aConnectionSite
;
1195 mrCustomShapeProperties
.getConnectionSiteList().push_back( aConnectionSite
);
1196 return new ConnectionSiteContext( *this, rAttribs
, mrCustomShapeProperties
, mrCustomShapeProperties
.getConnectionSiteList().back() );
1202 // CT_PresetGeometry2D
1203 PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
)
1204 : ContextHandler2( rParent
)
1205 , mrCustomShapeProperties( rCustomShapeProperties
)
1207 sal_Int32 nShapeType
= rAttribs
.getToken( XML_prst
, FastToken::DONTKNOW
);
1208 OSL_ENSURE( nShapeType
!= FastToken::DONTKNOW
, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1209 mrCustomShapeProperties
.setShapePresetType( nShapeType
);
1212 ContextHandlerRef
PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& )
1214 if ( aElementToken
== A_TOKEN( avLst
) )
1215 return new GeomGuideListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getAdjustmentGuideList() );
1220 // CT_PresetTextShape
1221 PresetTextShapeContext::PresetTextShapeContext( ContextHandler2Helper
& rParent
, const AttributeList
& rAttribs
, CustomShapeProperties
& rCustomShapeProperties
)
1222 : ContextHandler2( rParent
)
1223 , mrCustomShapeProperties( rCustomShapeProperties
)
1225 sal_Int32 nShapeType
= rAttribs
.getToken( XML_prst
, FastToken::DONTKNOW
);
1226 OSL_ENSURE( nShapeType
!= FastToken::DONTKNOW
, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1227 mrCustomShapeProperties
.setShapePresetType( nShapeType
);
1230 ContextHandlerRef
PresetTextShapeContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& )
1232 if ( aElementToken
== A_TOKEN( avLst
) )
1233 return new GeomGuideListContext( *this, mrCustomShapeProperties
, mrCustomShapeProperties
.getAdjustmentGuideList() );
1240 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */