1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*f6e50924SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*f6e50924SAndrew Rist * distributed with this work for additional information
6*f6e50924SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*f6e50924SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*f6e50924SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*f6e50924SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist * KIND, either express or implied. See the License for the
17*f6e50924SAndrew Rist * specific language governing permissions and limitations
18*f6e50924SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*f6e50924SAndrew Rist *************************************************************/
21*f6e50924SAndrew Rist
22*f6e50924SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include "svx/EnhancedCustomShape2d.hxx"
27cdf0e10cSrcweir #include <rtl/ustring.hxx>
28cdf0e10cSrcweir #include <tools/fract.hxx>
29cdf0e10cSrcweir
30cdf0e10cSrcweir // Makes parser a static resource,
31cdf0e10cSrcweir // we're synchronized externally.
32cdf0e10cSrcweir // But watch out, the parser might have
33cdf0e10cSrcweir // state not visible to this code!
34cdf0e10cSrcweir
35cdf0e10cSrcweir #define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
36cdf0e10cSrcweir #if defined(VERBOSE) && defined(DBG_UTIL)
37cdf0e10cSrcweir #include <typeinfo>
38cdf0e10cSrcweir #define BOOST_SPIRIT_DEBUG
39cdf0e10cSrcweir #endif
40cdf0e10cSrcweir #include <boost/spirit/include/classic_core.hpp>
41cdf0e10cSrcweir
42cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 0)
43cdf0e10cSrcweir #include <iostream>
44cdf0e10cSrcweir #endif
45cdf0e10cSrcweir #include <functional>
46cdf0e10cSrcweir #include <algorithm>
47cdf0e10cSrcweir #include <stack>
48cdf0e10cSrcweir
49cdf0e10cSrcweir #include <math.h> // fabs, sqrt, sin, cos, tan, atan, atan2
50cdf0e10cSrcweir using namespace EnhancedCustomShape;
51cdf0e10cSrcweir using namespace com::sun::star;
52cdf0e10cSrcweir using namespace com::sun::star::drawing;
53cdf0e10cSrcweir
FillEquationParameter(const EnhancedCustomShapeParameter & rSource,const sal_Int32 nDestPara,EnhancedCustomShapeEquation & rDest)54cdf0e10cSrcweir void EnhancedCustomShape::FillEquationParameter( const EnhancedCustomShapeParameter& rSource, const sal_Int32 nDestPara, EnhancedCustomShapeEquation& rDest )
55cdf0e10cSrcweir {
56cdf0e10cSrcweir sal_Int32 nValue = 0;
57cdf0e10cSrcweir if ( rSource.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
58cdf0e10cSrcweir {
59cdf0e10cSrcweir double fValue;
60cdf0e10cSrcweir if ( rSource.Value >>= fValue )
61cdf0e10cSrcweir nValue = (sal_Int32)fValue;
62cdf0e10cSrcweir }
63cdf0e10cSrcweir else
64cdf0e10cSrcweir rSource.Value >>= nValue;
65cdf0e10cSrcweir
66cdf0e10cSrcweir switch( rSource.Type )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION :
69cdf0e10cSrcweir {
70cdf0e10cSrcweir if ( nValue & 0x40000000 )
71cdf0e10cSrcweir {
72cdf0e10cSrcweir nValue ^= 0x40000000;
73cdf0e10cSrcweir rDest.nOperation |= 0x20000000 << nDestPara; // the bit is indicating that this value has to be adjusted later
74cdf0e10cSrcweir }
75cdf0e10cSrcweir nValue |= 0x400;
76cdf0e10cSrcweir }
77cdf0e10cSrcweir break;
78cdf0e10cSrcweir case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT : nValue += DFF_Prop_adjustValue; break;
79cdf0e10cSrcweir case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM : nValue = DFF_Prop_geoBottom; break;
80cdf0e10cSrcweir case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT : nValue = DFF_Prop_geoRight; break;
81cdf0e10cSrcweir case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP : nValue = DFF_Prop_geoTop; break;
82cdf0e10cSrcweir case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT : nValue = DFF_Prop_geoLeft; break;
83cdf0e10cSrcweir }
84cdf0e10cSrcweir if ( rSource.Type != com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL )
85cdf0e10cSrcweir rDest.nOperation |= ( 0x2000 << nDestPara );
86cdf0e10cSrcweir rDest.nPara[ nDestPara ] = nValue;
87cdf0e10cSrcweir }
88cdf0e10cSrcweir
~ExpressionNode()89cdf0e10cSrcweir ExpressionNode::~ExpressionNode()
90cdf0e10cSrcweir {}
91cdf0e10cSrcweir
92cdf0e10cSrcweir namespace
93cdf0e10cSrcweir {
94cdf0e10cSrcweir
95cdf0e10cSrcweir //////////////////////
96cdf0e10cSrcweir //////////////////////
97cdf0e10cSrcweir // EXPRESSION NODES
98cdf0e10cSrcweir //////////////////////
99cdf0e10cSrcweir //////////////////////
100cdf0e10cSrcweir class ConstantValueExpression : public ExpressionNode
101cdf0e10cSrcweir {
102cdf0e10cSrcweir double maValue;
103cdf0e10cSrcweir
104cdf0e10cSrcweir public:
105cdf0e10cSrcweir
ConstantValueExpression(double rValue)106cdf0e10cSrcweir ConstantValueExpression( double rValue ) :
107cdf0e10cSrcweir maValue( rValue )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir }
operator ()() const110cdf0e10cSrcweir virtual double operator()() const
111cdf0e10cSrcweir {
112cdf0e10cSrcweir return maValue;
113cdf0e10cSrcweir }
isConstant() const114cdf0e10cSrcweir virtual bool isConstant() const
115cdf0e10cSrcweir {
116cdf0e10cSrcweir return true;
117cdf0e10cSrcweir }
getType() const118cdf0e10cSrcweir virtual ExpressionFunct getType() const
119cdf0e10cSrcweir {
120cdf0e10cSrcweir return FUNC_CONST;
121cdf0e10cSrcweir }
fillNode(std::vector<EnhancedCustomShapeEquation> & rEquations,ExpressionNode *,sal_uInt32)122cdf0e10cSrcweir virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations, ExpressionNode* /* pOptionalArg */, sal_uInt32 /* nFlags */ )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir EnhancedCustomShapeParameter aRet;
125cdf0e10cSrcweir Fraction aFract( maValue );
126cdf0e10cSrcweir if ( aFract.GetDenominator() == 1 )
127cdf0e10cSrcweir {
128cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
129cdf0e10cSrcweir aRet.Value <<= (sal_Int32)aFract.GetNumerator();
130cdf0e10cSrcweir }
131cdf0e10cSrcweir else
132cdf0e10cSrcweir {
133cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
134cdf0e10cSrcweir aEquation.nOperation = 1;
135cdf0e10cSrcweir aEquation.nPara[ 0 ] = 1;
136cdf0e10cSrcweir aEquation.nPara[ 1 ] = (sal_Int16)aFract.GetNumerator();
137cdf0e10cSrcweir aEquation.nPara[ 2 ] = (sal_Int16)aFract.GetDenominator();
138cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
139cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
140cdf0e10cSrcweir rEquations.push_back( aEquation );
141cdf0e10cSrcweir }
142cdf0e10cSrcweir return aRet;
143cdf0e10cSrcweir }
144cdf0e10cSrcweir };
145cdf0e10cSrcweir
146cdf0e10cSrcweir class AdjustmentExpression : public ExpressionNode
147cdf0e10cSrcweir {
148cdf0e10cSrcweir sal_Int32 mnIndex;
149cdf0e10cSrcweir const EnhancedCustomShape2d& mrCustoShape;
150cdf0e10cSrcweir
151cdf0e10cSrcweir public:
152cdf0e10cSrcweir
AdjustmentExpression(const EnhancedCustomShape2d & rCustoShape,sal_Int32 nIndex)153cdf0e10cSrcweir AdjustmentExpression( const EnhancedCustomShape2d& rCustoShape, sal_Int32 nIndex )
154cdf0e10cSrcweir : mnIndex ( nIndex )
155cdf0e10cSrcweir , mrCustoShape( rCustoShape )
156cdf0e10cSrcweir
157cdf0e10cSrcweir {
158cdf0e10cSrcweir }
operator ()() const159cdf0e10cSrcweir virtual double operator()() const
160cdf0e10cSrcweir {
161cdf0e10cSrcweir return mrCustoShape.GetAdjustValueAsDouble( mnIndex );
162cdf0e10cSrcweir }
isConstant() const163cdf0e10cSrcweir virtual bool isConstant() const
164cdf0e10cSrcweir {
165cdf0e10cSrcweir return false;
166cdf0e10cSrcweir }
getType() const167cdf0e10cSrcweir virtual ExpressionFunct getType() const
168cdf0e10cSrcweir {
169cdf0e10cSrcweir return ENUM_FUNC_ADJUSTMENT;
170cdf0e10cSrcweir }
fillNode(std::vector<EnhancedCustomShapeEquation> &,ExpressionNode *,sal_uInt32)171cdf0e10cSrcweir virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& /*rEquations*/, ExpressionNode* /*pOptionalArg*/, sal_uInt32 /*nFlags*/ )
172cdf0e10cSrcweir {
173cdf0e10cSrcweir EnhancedCustomShapeParameter aRet;
174cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
175cdf0e10cSrcweir aRet.Value <<= mnIndex;
176cdf0e10cSrcweir return aRet;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir };
179cdf0e10cSrcweir
180cdf0e10cSrcweir class EquationExpression : public ExpressionNode
181cdf0e10cSrcweir {
182cdf0e10cSrcweir sal_Int32 mnIndex;
183cdf0e10cSrcweir const EnhancedCustomShape2d& mrCustoShape;
184cdf0e10cSrcweir
185cdf0e10cSrcweir public:
186cdf0e10cSrcweir
EquationExpression(const EnhancedCustomShape2d & rCustoShape,sal_Int32 nIndex)187cdf0e10cSrcweir EquationExpression( const EnhancedCustomShape2d& rCustoShape, sal_Int32 nIndex )
188cdf0e10cSrcweir : mnIndex ( nIndex )
189cdf0e10cSrcweir , mrCustoShape( rCustoShape )
190cdf0e10cSrcweir {
191cdf0e10cSrcweir }
operator ()() const192cdf0e10cSrcweir virtual double operator()() const
193cdf0e10cSrcweir {
194cdf0e10cSrcweir return mrCustoShape.GetEquationValueAsDouble( mnIndex );
195cdf0e10cSrcweir }
isConstant() const196cdf0e10cSrcweir virtual bool isConstant() const
197cdf0e10cSrcweir {
198cdf0e10cSrcweir return false;
199cdf0e10cSrcweir }
getType() const200cdf0e10cSrcweir virtual ExpressionFunct getType() const
201cdf0e10cSrcweir {
202cdf0e10cSrcweir return ENUM_FUNC_EQUATION;
203cdf0e10cSrcweir }
fillNode(std::vector<EnhancedCustomShapeEquation> &,ExpressionNode *,sal_uInt32)204cdf0e10cSrcweir virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& /*rEquations*/, ExpressionNode* /*pOptionalArg*/, sal_uInt32 /*nFlags*/ )
205cdf0e10cSrcweir {
206cdf0e10cSrcweir EnhancedCustomShapeParameter aRet;
207cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
208cdf0e10cSrcweir aRet.Value <<= mnIndex | 0x40000000; // the bit is indicating that this equation needs to be adjusted later
209cdf0e10cSrcweir return aRet;
210cdf0e10cSrcweir }
211cdf0e10cSrcweir };
212cdf0e10cSrcweir
213cdf0e10cSrcweir class EnumValueExpression : public ExpressionNode
214cdf0e10cSrcweir {
215cdf0e10cSrcweir const ExpressionFunct meFunct;
216cdf0e10cSrcweir const EnhancedCustomShape2d& mrCustoShape;
217cdf0e10cSrcweir
218cdf0e10cSrcweir public:
219cdf0e10cSrcweir
EnumValueExpression(const EnhancedCustomShape2d & rCustoShape,const ExpressionFunct eFunct)220cdf0e10cSrcweir EnumValueExpression( const EnhancedCustomShape2d& rCustoShape, const ExpressionFunct eFunct )
221cdf0e10cSrcweir : meFunct ( eFunct )
222cdf0e10cSrcweir , mrCustoShape ( rCustoShape )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir }
getValue(const EnhancedCustomShape2d & rCustoShape,const ExpressionFunct eFunc)225cdf0e10cSrcweir static double getValue( const EnhancedCustomShape2d& rCustoShape, const ExpressionFunct eFunc )
226cdf0e10cSrcweir {
227cdf0e10cSrcweir EnhancedCustomShape2d::EnumFunc eF;
228cdf0e10cSrcweir switch( eFunc )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir case ENUM_FUNC_PI : eF = EnhancedCustomShape2d::ENUM_FUNC_PI; break;
231cdf0e10cSrcweir case ENUM_FUNC_LEFT : eF = EnhancedCustomShape2d::ENUM_FUNC_LEFT; break;
232cdf0e10cSrcweir case ENUM_FUNC_TOP : eF = EnhancedCustomShape2d::ENUM_FUNC_TOP; break;
233cdf0e10cSrcweir case ENUM_FUNC_RIGHT : eF = EnhancedCustomShape2d::ENUM_FUNC_RIGHT; break;
234cdf0e10cSrcweir case ENUM_FUNC_BOTTOM : eF = EnhancedCustomShape2d::ENUM_FUNC_BOTTOM; break;
235cdf0e10cSrcweir case ENUM_FUNC_XSTRETCH : eF = EnhancedCustomShape2d::ENUM_FUNC_XSTRETCH; break;
236cdf0e10cSrcweir case ENUM_FUNC_YSTRETCH : eF = EnhancedCustomShape2d::ENUM_FUNC_YSTRETCH; break;
237cdf0e10cSrcweir case ENUM_FUNC_HASSTROKE : eF = EnhancedCustomShape2d::ENUM_FUNC_HASSTROKE; break;
238cdf0e10cSrcweir case ENUM_FUNC_HASFILL : eF = EnhancedCustomShape2d::ENUM_FUNC_HASFILL; break;
239cdf0e10cSrcweir case ENUM_FUNC_WIDTH : eF = EnhancedCustomShape2d::ENUM_FUNC_WIDTH; break;
240cdf0e10cSrcweir case ENUM_FUNC_HEIGHT : eF = EnhancedCustomShape2d::ENUM_FUNC_HEIGHT; break;
241cdf0e10cSrcweir case ENUM_FUNC_LOGWIDTH : eF = EnhancedCustomShape2d::ENUM_FUNC_LOGWIDTH; break;
242cdf0e10cSrcweir case ENUM_FUNC_LOGHEIGHT : eF = EnhancedCustomShape2d::ENUM_FUNC_LOGHEIGHT; break;
243cdf0e10cSrcweir
244cdf0e10cSrcweir default :
245cdf0e10cSrcweir return 0.0;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir return rCustoShape.GetEnumFunc( eF );
248cdf0e10cSrcweir }
operator ()() const249cdf0e10cSrcweir virtual double operator()() const
250cdf0e10cSrcweir {
251cdf0e10cSrcweir return getValue( mrCustoShape, meFunct );
252cdf0e10cSrcweir }
isConstant() const253cdf0e10cSrcweir virtual bool isConstant() const
254cdf0e10cSrcweir {
255cdf0e10cSrcweir return false;
256cdf0e10cSrcweir }
getType() const257cdf0e10cSrcweir virtual ExpressionFunct getType() const
258cdf0e10cSrcweir {
259cdf0e10cSrcweir return meFunct;
260cdf0e10cSrcweir }
fillNode(std::vector<EnhancedCustomShapeEquation> & rEquations,ExpressionNode *,sal_uInt32 nFlags)261cdf0e10cSrcweir virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations, ExpressionNode* /*pOptionalArg*/, sal_uInt32 nFlags )
262cdf0e10cSrcweir {
263cdf0e10cSrcweir EnhancedCustomShapeParameter aRet;
264cdf0e10cSrcweir
265cdf0e10cSrcweir sal_Int32 nDummy = 1;
266cdf0e10cSrcweir aRet.Value <<= nDummy;
267cdf0e10cSrcweir
268cdf0e10cSrcweir switch( meFunct )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir case ENUM_FUNC_WIDTH : // TODO: do not use this as constant value
271cdf0e10cSrcweir case ENUM_FUNC_HEIGHT :
272cdf0e10cSrcweir case ENUM_FUNC_LOGWIDTH :
273cdf0e10cSrcweir case ENUM_FUNC_LOGHEIGHT :
274cdf0e10cSrcweir case ENUM_FUNC_PI :
275cdf0e10cSrcweir {
276cdf0e10cSrcweir ConstantValueExpression aConstantValue( getValue( mrCustoShape, meFunct ) );
277cdf0e10cSrcweir aRet = aConstantValue.fillNode( rEquations, NULL, nFlags );
278cdf0e10cSrcweir }
279cdf0e10cSrcweir break;
280cdf0e10cSrcweir case ENUM_FUNC_LEFT : aRet.Type = EnhancedCustomShapeParameterType::LEFT; break;
281cdf0e10cSrcweir case ENUM_FUNC_TOP : aRet.Type = EnhancedCustomShapeParameterType::TOP; break;
282cdf0e10cSrcweir case ENUM_FUNC_RIGHT : aRet.Type = EnhancedCustomShapeParameterType::RIGHT; break;
283cdf0e10cSrcweir case ENUM_FUNC_BOTTOM : aRet.Type = EnhancedCustomShapeParameterType::BOTTOM; break;
284cdf0e10cSrcweir
285cdf0e10cSrcweir // not implemented so far
286cdf0e10cSrcweir case ENUM_FUNC_XSTRETCH :
287cdf0e10cSrcweir case ENUM_FUNC_YSTRETCH :
288cdf0e10cSrcweir case ENUM_FUNC_HASSTROKE :
289cdf0e10cSrcweir case ENUM_FUNC_HASFILL : aRet.Type = EnhancedCustomShapeParameterType::NORMAL; break;
290cdf0e10cSrcweir
291cdf0e10cSrcweir default:
292cdf0e10cSrcweir break;
293cdf0e10cSrcweir }
294cdf0e10cSrcweir return aRet;
295cdf0e10cSrcweir }
296cdf0e10cSrcweir };
297cdf0e10cSrcweir
298cdf0e10cSrcweir /** ExpressionNode implementation for unary
299cdf0e10cSrcweir function over one ExpressionNode
300cdf0e10cSrcweir */
301cdf0e10cSrcweir class UnaryFunctionExpression : public ExpressionNode
302cdf0e10cSrcweir {
303cdf0e10cSrcweir const ExpressionFunct meFunct;
304cdf0e10cSrcweir ExpressionNodeSharedPtr mpArg;
305cdf0e10cSrcweir
306cdf0e10cSrcweir public:
UnaryFunctionExpression(const ExpressionFunct eFunct,const ExpressionNodeSharedPtr & rArg)307cdf0e10cSrcweir UnaryFunctionExpression( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rArg ) :
308cdf0e10cSrcweir meFunct( eFunct ),
309cdf0e10cSrcweir mpArg( rArg )
310cdf0e10cSrcweir {
311cdf0e10cSrcweir }
getValue(const ExpressionFunct eFunct,const ExpressionNodeSharedPtr & rArg)312cdf0e10cSrcweir static double getValue( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rArg )
313cdf0e10cSrcweir {
314cdf0e10cSrcweir double fRet = 0;
315cdf0e10cSrcweir switch( eFunct )
316cdf0e10cSrcweir {
317cdf0e10cSrcweir case UNARY_FUNC_ABS : fRet = fabs( (*rArg)() ); break;
318cdf0e10cSrcweir case UNARY_FUNC_SQRT: fRet = sqrt( (*rArg)() ); break;
319cdf0e10cSrcweir case UNARY_FUNC_SIN : fRet = sin( (*rArg)() ); break;
320cdf0e10cSrcweir case UNARY_FUNC_COS : fRet = cos( (*rArg)() ); break;
321cdf0e10cSrcweir case UNARY_FUNC_TAN : fRet = tan( (*rArg)() ); break;
322cdf0e10cSrcweir case UNARY_FUNC_ATAN: fRet = atan( (*rArg)() ); break;
323cdf0e10cSrcweir case UNARY_FUNC_NEG : fRet = ::std::negate<double>()( (*rArg)() ); break;
324cdf0e10cSrcweir default:
325cdf0e10cSrcweir break;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir return fRet;
328cdf0e10cSrcweir }
operator ()() const329cdf0e10cSrcweir virtual double operator()() const
330cdf0e10cSrcweir {
331cdf0e10cSrcweir return getValue( meFunct, mpArg );
332cdf0e10cSrcweir }
isConstant() const333cdf0e10cSrcweir virtual bool isConstant() const
334cdf0e10cSrcweir {
335cdf0e10cSrcweir return mpArg->isConstant();
336cdf0e10cSrcweir }
getType() const337cdf0e10cSrcweir virtual ExpressionFunct getType() const
338cdf0e10cSrcweir {
339cdf0e10cSrcweir return meFunct;
340cdf0e10cSrcweir }
fillNode(std::vector<EnhancedCustomShapeEquation> & rEquations,ExpressionNode * pOptionalArg,sal_uInt32 nFlags)341cdf0e10cSrcweir virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations, ExpressionNode* pOptionalArg, sal_uInt32 nFlags )
342cdf0e10cSrcweir {
343cdf0e10cSrcweir EnhancedCustomShapeParameter aRet;
344cdf0e10cSrcweir switch( meFunct )
345cdf0e10cSrcweir {
346cdf0e10cSrcweir case UNARY_FUNC_ABS :
347cdf0e10cSrcweir {
348cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
349cdf0e10cSrcweir aEquation.nOperation |= 3;
350cdf0e10cSrcweir FillEquationParameter( mpArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
351cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
352cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
353cdf0e10cSrcweir rEquations.push_back( aEquation );
354cdf0e10cSrcweir }
355cdf0e10cSrcweir break;
356cdf0e10cSrcweir case UNARY_FUNC_SQRT:
357cdf0e10cSrcweir {
358cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
359cdf0e10cSrcweir aEquation.nOperation |= 13;
360cdf0e10cSrcweir FillEquationParameter( mpArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
361cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
362cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
363cdf0e10cSrcweir rEquations.push_back( aEquation );
364cdf0e10cSrcweir }
365cdf0e10cSrcweir break;
366cdf0e10cSrcweir case UNARY_FUNC_SIN :
367cdf0e10cSrcweir {
368cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
369cdf0e10cSrcweir aEquation.nOperation |= 9;
370cdf0e10cSrcweir if ( pOptionalArg )
371cdf0e10cSrcweir FillEquationParameter( pOptionalArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
372cdf0e10cSrcweir else
373cdf0e10cSrcweir aEquation.nPara[ 0 ] = 1;
374cdf0e10cSrcweir
375cdf0e10cSrcweir EnhancedCustomShapeParameter aSource( mpArg->fillNode( rEquations, NULL, nFlags | EXPRESSION_FLAG_SUMANGLE_MODE ) );
376cdf0e10cSrcweir if ( aSource.Type == EnhancedCustomShapeParameterType::NORMAL )
377cdf0e10cSrcweir { // sumangle needed :-(
378cdf0e10cSrcweir EnhancedCustomShapeEquation _aEquation;
379cdf0e10cSrcweir _aEquation.nOperation |= 0xe; // sumangle
380cdf0e10cSrcweir FillEquationParameter( aSource, 1, _aEquation );
381cdf0e10cSrcweir aSource.Type = EnhancedCustomShapeParameterType::EQUATION;
382cdf0e10cSrcweir aSource.Value <<= (sal_Int32)rEquations.size();
383cdf0e10cSrcweir rEquations.push_back( _aEquation );
384cdf0e10cSrcweir }
385cdf0e10cSrcweir FillEquationParameter( aSource, 1, aEquation );
386cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
387cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
388cdf0e10cSrcweir rEquations.push_back( aEquation );
389cdf0e10cSrcweir }
390cdf0e10cSrcweir break;
391cdf0e10cSrcweir case UNARY_FUNC_COS :
392cdf0e10cSrcweir {
393cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
394cdf0e10cSrcweir aEquation.nOperation |= 10;
395cdf0e10cSrcweir if ( pOptionalArg )
396cdf0e10cSrcweir FillEquationParameter( pOptionalArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
397cdf0e10cSrcweir else
398cdf0e10cSrcweir aEquation.nPara[ 0 ] = 1;
399cdf0e10cSrcweir
400cdf0e10cSrcweir EnhancedCustomShapeParameter aSource( mpArg->fillNode( rEquations, NULL, nFlags | EXPRESSION_FLAG_SUMANGLE_MODE ) );
401cdf0e10cSrcweir if ( aSource.Type == EnhancedCustomShapeParameterType::NORMAL )
402cdf0e10cSrcweir { // sumangle needed :-(
403cdf0e10cSrcweir EnhancedCustomShapeEquation aTmpEquation;
404cdf0e10cSrcweir aTmpEquation.nOperation |= 0xe; // sumangle
405cdf0e10cSrcweir FillEquationParameter( aSource, 1, aTmpEquation );
406cdf0e10cSrcweir aSource.Type = EnhancedCustomShapeParameterType::EQUATION;
407cdf0e10cSrcweir aSource.Value <<= (sal_Int32)rEquations.size();
408cdf0e10cSrcweir rEquations.push_back( aTmpEquation );
409cdf0e10cSrcweir }
410cdf0e10cSrcweir FillEquationParameter( aSource, 1, aEquation );
411cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
412cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
413cdf0e10cSrcweir rEquations.push_back( aEquation );
414cdf0e10cSrcweir }
415cdf0e10cSrcweir break;
416cdf0e10cSrcweir case UNARY_FUNC_TAN :
417cdf0e10cSrcweir {
418cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
419cdf0e10cSrcweir aEquation.nOperation |= 16;
420cdf0e10cSrcweir if ( pOptionalArg )
421cdf0e10cSrcweir FillEquationParameter( pOptionalArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
422cdf0e10cSrcweir else
423cdf0e10cSrcweir aEquation.nPara[ 0 ] = 1;
424cdf0e10cSrcweir
425cdf0e10cSrcweir EnhancedCustomShapeParameter aSource( mpArg->fillNode( rEquations, NULL, nFlags | EXPRESSION_FLAG_SUMANGLE_MODE ) );
426cdf0e10cSrcweir if ( aSource.Type == EnhancedCustomShapeParameterType::NORMAL )
427cdf0e10cSrcweir { // sumangle needed :-(
428cdf0e10cSrcweir EnhancedCustomShapeEquation aTmpEquation;
429cdf0e10cSrcweir aTmpEquation.nOperation |= 0xe; // sumangle
430cdf0e10cSrcweir FillEquationParameter( aSource, 1, aTmpEquation );
431cdf0e10cSrcweir aSource.Type = EnhancedCustomShapeParameterType::EQUATION;
432cdf0e10cSrcweir aSource.Value <<= (sal_Int32)rEquations.size();
433cdf0e10cSrcweir rEquations.push_back( aTmpEquation );
434cdf0e10cSrcweir }
435cdf0e10cSrcweir FillEquationParameter( aSource, 1, aEquation );
436cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
437cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
438cdf0e10cSrcweir rEquations.push_back( aEquation );
439cdf0e10cSrcweir }
440cdf0e10cSrcweir break;
441cdf0e10cSrcweir case UNARY_FUNC_ATAN:
442cdf0e10cSrcweir {
443cdf0e10cSrcweir // TODO:
444cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
445cdf0e10cSrcweir }
446cdf0e10cSrcweir break;
447cdf0e10cSrcweir case UNARY_FUNC_NEG:
448cdf0e10cSrcweir {
449cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
450cdf0e10cSrcweir aEquation.nOperation |= 1;
451cdf0e10cSrcweir aEquation.nPara[ 1 ] = -1;
452cdf0e10cSrcweir aEquation.nPara[ 2 ] = 1;
453cdf0e10cSrcweir FillEquationParameter( mpArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
454cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
455cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
456cdf0e10cSrcweir rEquations.push_back( aEquation );
457cdf0e10cSrcweir }
458cdf0e10cSrcweir break;
459cdf0e10cSrcweir default:
460cdf0e10cSrcweir break;
461cdf0e10cSrcweir }
462cdf0e10cSrcweir return aRet;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir };
465cdf0e10cSrcweir
466cdf0e10cSrcweir /** ExpressionNode implementation for unary
467cdf0e10cSrcweir function over two ExpressionNodes
468cdf0e10cSrcweir */
469cdf0e10cSrcweir class BinaryFunctionExpression : public ExpressionNode
470cdf0e10cSrcweir {
471cdf0e10cSrcweir const ExpressionFunct meFunct;
472cdf0e10cSrcweir ExpressionNodeSharedPtr mpFirstArg;
473cdf0e10cSrcweir ExpressionNodeSharedPtr mpSecondArg;
474cdf0e10cSrcweir
475cdf0e10cSrcweir public:
476cdf0e10cSrcweir
BinaryFunctionExpression(const ExpressionFunct eFunct,const ExpressionNodeSharedPtr & rFirstArg,const ExpressionNodeSharedPtr & rSecondArg)477cdf0e10cSrcweir BinaryFunctionExpression( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rFirstArg, const ExpressionNodeSharedPtr& rSecondArg ) :
478cdf0e10cSrcweir meFunct( eFunct ),
479cdf0e10cSrcweir mpFirstArg( rFirstArg ),
480cdf0e10cSrcweir mpSecondArg( rSecondArg )
481cdf0e10cSrcweir {
482cdf0e10cSrcweir }
getValue(const ExpressionFunct eFunct,const ExpressionNodeSharedPtr & rFirstArg,const ExpressionNodeSharedPtr & rSecondArg)483cdf0e10cSrcweir static double getValue( const ExpressionFunct eFunct, const ExpressionNodeSharedPtr& rFirstArg, const ExpressionNodeSharedPtr& rSecondArg )
484cdf0e10cSrcweir {
485cdf0e10cSrcweir double fRet = 0;
486cdf0e10cSrcweir switch( eFunct )
487cdf0e10cSrcweir {
488cdf0e10cSrcweir case BINARY_FUNC_PLUS : fRet = (*rFirstArg)() + (*rSecondArg)(); break;
489cdf0e10cSrcweir case BINARY_FUNC_MINUS: fRet = (*rFirstArg)() - (*rSecondArg)(); break;
490cdf0e10cSrcweir case BINARY_FUNC_MUL : fRet = (*rFirstArg)() * (*rSecondArg)(); break;
491cdf0e10cSrcweir case BINARY_FUNC_DIV : fRet = (*rFirstArg)() / (*rSecondArg)(); break;
492cdf0e10cSrcweir case BINARY_FUNC_MIN : fRet = ::std::min( (*rFirstArg)(), (*rSecondArg)() ); break;
493cdf0e10cSrcweir case BINARY_FUNC_MAX : fRet = ::std::max( (*rFirstArg)(), (*rSecondArg)() ); break;
494cdf0e10cSrcweir case BINARY_FUNC_ATAN2: fRet = atan2( (*rFirstArg)(), (*rSecondArg)() ); break;
495cdf0e10cSrcweir default:
496cdf0e10cSrcweir break;
497cdf0e10cSrcweir }
498cdf0e10cSrcweir return fRet;
499cdf0e10cSrcweir }
operator ()() const500cdf0e10cSrcweir virtual double operator()() const
501cdf0e10cSrcweir {
502cdf0e10cSrcweir return getValue( meFunct, mpFirstArg, mpSecondArg );
503cdf0e10cSrcweir }
isConstant() const504cdf0e10cSrcweir virtual bool isConstant() const
505cdf0e10cSrcweir {
506cdf0e10cSrcweir return mpFirstArg->isConstant() && mpSecondArg->isConstant();
507cdf0e10cSrcweir }
getType() const508cdf0e10cSrcweir virtual ExpressionFunct getType() const
509cdf0e10cSrcweir {
510cdf0e10cSrcweir return meFunct;
511cdf0e10cSrcweir }
fillNode(std::vector<EnhancedCustomShapeEquation> & rEquations,ExpressionNode *,sal_uInt32 nFlags)512cdf0e10cSrcweir virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations, ExpressionNode* /*pOptionalArg*/, sal_uInt32 nFlags )
513cdf0e10cSrcweir {
514cdf0e10cSrcweir EnhancedCustomShapeParameter aRet;
515cdf0e10cSrcweir switch( meFunct )
516cdf0e10cSrcweir {
517cdf0e10cSrcweir case BINARY_FUNC_PLUS :
518cdf0e10cSrcweir {
519cdf0e10cSrcweir if ( nFlags & EXPRESSION_FLAG_SUMANGLE_MODE )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir if ( mpFirstArg->getType() == ENUM_FUNC_ADJUSTMENT )
522cdf0e10cSrcweir {
523cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
524cdf0e10cSrcweir aEquation.nOperation |= 0xe; // sumangle
525cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
526cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 1, aEquation );
527cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
528cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
529cdf0e10cSrcweir rEquations.push_back( aEquation );
530cdf0e10cSrcweir }
531cdf0e10cSrcweir else if ( mpSecondArg->getType() == ENUM_FUNC_ADJUSTMENT )
532cdf0e10cSrcweir {
533cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
534cdf0e10cSrcweir aEquation.nOperation |= 0xe; // sumangle
535cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
536cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 1, aEquation );
537cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
538cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
539cdf0e10cSrcweir rEquations.push_back( aEquation );
540cdf0e10cSrcweir }
541cdf0e10cSrcweir else
542cdf0e10cSrcweir {
543cdf0e10cSrcweir EnhancedCustomShapeEquation aSumangle1;
544cdf0e10cSrcweir aSumangle1.nOperation |= 0xe; // sumangle
545cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags &~EXPRESSION_FLAG_SUMANGLE_MODE ), 1, aSumangle1 );
546cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
547cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
548cdf0e10cSrcweir rEquations.push_back( aSumangle1 );
549cdf0e10cSrcweir
550cdf0e10cSrcweir EnhancedCustomShapeEquation aSumangle2;
551cdf0e10cSrcweir aSumangle2.nOperation |= 0xe; // sumangle
552cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags &~EXPRESSION_FLAG_SUMANGLE_MODE ), 1, aSumangle2 );
553cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
554cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
555cdf0e10cSrcweir rEquations.push_back( aSumangle2 );
556cdf0e10cSrcweir
557cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
558cdf0e10cSrcweir aEquation.nOperation |= 0;
559cdf0e10cSrcweir aEquation.nPara[ 0 ] = ( rEquations.size() - 2 ) | 0x400;
560cdf0e10cSrcweir aEquation.nPara[ 1 ] = ( rEquations.size() - 1 ) | 0x400;
561cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
562cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
563cdf0e10cSrcweir rEquations.push_back( aEquation );
564cdf0e10cSrcweir }
565cdf0e10cSrcweir }
566cdf0e10cSrcweir else
567cdf0e10cSrcweir {
568cdf0e10cSrcweir sal_Bool bFirstIsEmpty = mpFirstArg->isConstant() && ( (*mpFirstArg)() == 0 );
569cdf0e10cSrcweir sal_Bool bSecondIsEmpty = mpSecondArg->isConstant() && ( (*mpSecondArg)() == 0 );
570cdf0e10cSrcweir
571cdf0e10cSrcweir if ( bFirstIsEmpty )
572cdf0e10cSrcweir aRet = mpSecondArg->fillNode( rEquations, NULL, nFlags );
573cdf0e10cSrcweir else if ( bSecondIsEmpty )
574cdf0e10cSrcweir aRet = mpFirstArg->fillNode( rEquations, NULL, nFlags );
575cdf0e10cSrcweir else
576cdf0e10cSrcweir {
577cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
578cdf0e10cSrcweir aEquation.nOperation |= 0;
579cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
580cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 1, aEquation );
581cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
582cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
583cdf0e10cSrcweir rEquations.push_back( aEquation );
584cdf0e10cSrcweir }
585cdf0e10cSrcweir }
586cdf0e10cSrcweir }
587cdf0e10cSrcweir break;
588cdf0e10cSrcweir case BINARY_FUNC_MINUS:
589cdf0e10cSrcweir {
590cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
591cdf0e10cSrcweir aEquation.nOperation |= 0;
592cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
593cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 2, aEquation );
594cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
595cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
596cdf0e10cSrcweir rEquations.push_back( aEquation );
597cdf0e10cSrcweir }
598cdf0e10cSrcweir break;
599cdf0e10cSrcweir case BINARY_FUNC_MUL :
600cdf0e10cSrcweir {
601cdf0e10cSrcweir // in the dest. format the cos function is using integer as result :-(
602cdf0e10cSrcweir // so we can't use the generic algorithm
603cdf0e10cSrcweir if ( ( mpFirstArg->getType() == UNARY_FUNC_SIN ) || ( mpFirstArg->getType() == UNARY_FUNC_COS ) || ( mpFirstArg->getType() == UNARY_FUNC_TAN ) )
604cdf0e10cSrcweir aRet = mpFirstArg->fillNode( rEquations, mpSecondArg.get(), nFlags );
605cdf0e10cSrcweir else if ( ( mpSecondArg->getType() == UNARY_FUNC_SIN ) || ( mpSecondArg->getType() == UNARY_FUNC_COS ) || ( mpSecondArg->getType() == UNARY_FUNC_TAN ) )
606cdf0e10cSrcweir aRet = mpSecondArg->fillNode( rEquations, mpFirstArg.get(), nFlags );
607cdf0e10cSrcweir else
608cdf0e10cSrcweir {
609cdf0e10cSrcweir if ( mpFirstArg->isConstant() && (*mpFirstArg)() == 1 )
610cdf0e10cSrcweir aRet = mpSecondArg->fillNode( rEquations, NULL, nFlags );
611cdf0e10cSrcweir else if ( mpSecondArg->isConstant() && (*mpSecondArg)() == 1 )
612cdf0e10cSrcweir aRet = mpFirstArg->fillNode( rEquations, NULL, nFlags );
613cdf0e10cSrcweir else if ( ( mpFirstArg->getType() == BINARY_FUNC_DIV ) // don't care of (pi/180)
614cdf0e10cSrcweir && ( ((BinaryFunctionExpression*)((BinaryFunctionExpression*)mpFirstArg.get())->mpFirstArg.get())->getType() == ENUM_FUNC_PI )
615cdf0e10cSrcweir && ( ((BinaryFunctionExpression*)((BinaryFunctionExpression*)mpFirstArg.get())->mpSecondArg.get())->getType() == FUNC_CONST ) )
616cdf0e10cSrcweir {
617cdf0e10cSrcweir aRet = mpSecondArg->fillNode( rEquations, NULL, nFlags );
618cdf0e10cSrcweir }
619cdf0e10cSrcweir else if ( ( mpSecondArg->getType() == BINARY_FUNC_DIV ) // don't care of (pi/180)
620cdf0e10cSrcweir && ( ((BinaryFunctionExpression*)((BinaryFunctionExpression*)mpSecondArg.get())->mpFirstArg.get())->getType() == ENUM_FUNC_PI )
621cdf0e10cSrcweir && ( ((BinaryFunctionExpression*)((BinaryFunctionExpression*)mpSecondArg.get())->mpSecondArg.get())->getType() == FUNC_CONST ) )
622cdf0e10cSrcweir {
623cdf0e10cSrcweir aRet = mpFirstArg->fillNode( rEquations, NULL, nFlags );
624cdf0e10cSrcweir }
625cdf0e10cSrcweir else
626cdf0e10cSrcweir {
627cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
628cdf0e10cSrcweir aEquation.nOperation |= 1;
629cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
630cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 1, aEquation );
631cdf0e10cSrcweir aEquation.nPara[ 2 ] = 1;
632cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
633cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
634cdf0e10cSrcweir rEquations.push_back( aEquation );
635cdf0e10cSrcweir }
636cdf0e10cSrcweir }
637cdf0e10cSrcweir }
638cdf0e10cSrcweir break;
639cdf0e10cSrcweir case BINARY_FUNC_DIV :
640cdf0e10cSrcweir {
641cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
642cdf0e10cSrcweir aEquation.nOperation |= 1;
643cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
644cdf0e10cSrcweir aEquation.nPara[ 1 ] = 1;
645cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 2, aEquation );
646cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
647cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
648cdf0e10cSrcweir rEquations.push_back( aEquation );
649cdf0e10cSrcweir }
650cdf0e10cSrcweir break;
651cdf0e10cSrcweir case BINARY_FUNC_MIN :
652cdf0e10cSrcweir {
653cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
654cdf0e10cSrcweir aEquation.nOperation |= 4;
655cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
656cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 1, aEquation );
657cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
658cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
659cdf0e10cSrcweir rEquations.push_back( aEquation );
660cdf0e10cSrcweir }
661cdf0e10cSrcweir break;
662cdf0e10cSrcweir case BINARY_FUNC_MAX :
663cdf0e10cSrcweir {
664cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
665cdf0e10cSrcweir aEquation.nOperation |= 5;
666cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
667cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 1, aEquation );
668cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
669cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
670cdf0e10cSrcweir rEquations.push_back( aEquation );
671cdf0e10cSrcweir }
672cdf0e10cSrcweir break;
673cdf0e10cSrcweir case BINARY_FUNC_ATAN2:
674cdf0e10cSrcweir {
675cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
676cdf0e10cSrcweir aEquation.nOperation |= 8;
677cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
678cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 1, aEquation );
679cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
680cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
681cdf0e10cSrcweir rEquations.push_back( aEquation );
682cdf0e10cSrcweir }
683cdf0e10cSrcweir break;
684cdf0e10cSrcweir default:
685cdf0e10cSrcweir break;
686cdf0e10cSrcweir }
687cdf0e10cSrcweir return aRet;
688cdf0e10cSrcweir }
689cdf0e10cSrcweir };
690cdf0e10cSrcweir
691cdf0e10cSrcweir class IfExpression : public ExpressionNode
692cdf0e10cSrcweir {
693cdf0e10cSrcweir ExpressionNodeSharedPtr mpFirstArg;
694cdf0e10cSrcweir ExpressionNodeSharedPtr mpSecondArg;
695cdf0e10cSrcweir ExpressionNodeSharedPtr mpThirdArg;
696cdf0e10cSrcweir
697cdf0e10cSrcweir public:
698cdf0e10cSrcweir
IfExpression(const ExpressionNodeSharedPtr & rFirstArg,const ExpressionNodeSharedPtr & rSecondArg,const ExpressionNodeSharedPtr & rThirdArg)699cdf0e10cSrcweir IfExpression( const ExpressionNodeSharedPtr& rFirstArg,
700cdf0e10cSrcweir const ExpressionNodeSharedPtr& rSecondArg,
701cdf0e10cSrcweir const ExpressionNodeSharedPtr& rThirdArg ) :
702cdf0e10cSrcweir mpFirstArg( rFirstArg ),
703cdf0e10cSrcweir mpSecondArg( rSecondArg ),
704cdf0e10cSrcweir mpThirdArg( rThirdArg )
705cdf0e10cSrcweir {
706cdf0e10cSrcweir }
isConstant() const707cdf0e10cSrcweir virtual bool isConstant() const
708cdf0e10cSrcweir {
709cdf0e10cSrcweir return
710cdf0e10cSrcweir mpFirstArg->isConstant() &&
711cdf0e10cSrcweir mpSecondArg->isConstant() &&
712cdf0e10cSrcweir mpThirdArg->isConstant();
713cdf0e10cSrcweir }
operator ()() const714cdf0e10cSrcweir virtual double operator()() const
715cdf0e10cSrcweir {
716cdf0e10cSrcweir return (*mpFirstArg)() > 0 ? (*mpSecondArg)() : (*mpThirdArg)();
717cdf0e10cSrcweir }
getType() const718cdf0e10cSrcweir virtual ExpressionFunct getType() const
719cdf0e10cSrcweir {
720cdf0e10cSrcweir return TERNARY_FUNC_IF;
721cdf0e10cSrcweir }
fillNode(std::vector<EnhancedCustomShapeEquation> & rEquations,ExpressionNode *,sal_uInt32 nFlags)722cdf0e10cSrcweir virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations, ExpressionNode* /*pOptionalArg*/, sal_uInt32 nFlags )
723cdf0e10cSrcweir {
724cdf0e10cSrcweir EnhancedCustomShapeParameter aRet;
725cdf0e10cSrcweir aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
726cdf0e10cSrcweir aRet.Value <<= (sal_Int32)rEquations.size();
727cdf0e10cSrcweir {
728cdf0e10cSrcweir EnhancedCustomShapeEquation aEquation;
729cdf0e10cSrcweir aEquation.nOperation |= 6;
730cdf0e10cSrcweir FillEquationParameter( mpFirstArg->fillNode( rEquations, NULL, nFlags ), 0, aEquation );
731cdf0e10cSrcweir FillEquationParameter( mpSecondArg->fillNode( rEquations, NULL, nFlags ), 1, aEquation );
732cdf0e10cSrcweir FillEquationParameter( mpThirdArg->fillNode( rEquations, NULL, nFlags ), 2, aEquation );
733cdf0e10cSrcweir rEquations.push_back( aEquation );
734cdf0e10cSrcweir }
735cdf0e10cSrcweir return aRet;
736cdf0e10cSrcweir }
737cdf0e10cSrcweir };
738cdf0e10cSrcweir
739cdf0e10cSrcweir ////////////////////////
740cdf0e10cSrcweir ////////////////////////
741cdf0e10cSrcweir // FUNCTION PARSER
742cdf0e10cSrcweir ////////////////////////
743cdf0e10cSrcweir ////////////////////////
744cdf0e10cSrcweir
745cdf0e10cSrcweir typedef const sal_Char* StringIteratorT;
746cdf0e10cSrcweir
747cdf0e10cSrcweir struct ParserContext
748cdf0e10cSrcweir {
749cdf0e10cSrcweir typedef ::std::stack< ExpressionNodeSharedPtr > OperandStack;
750cdf0e10cSrcweir
751cdf0e10cSrcweir // stores a stack of not-yet-evaluated operands. This is used
752cdf0e10cSrcweir // by the operators (i.e. '+', '*', 'sin' etc.) to pop their
753cdf0e10cSrcweir // arguments from. If all arguments to an operator are constant,
754cdf0e10cSrcweir // the operator pushes a precalculated result on the stack, and
755cdf0e10cSrcweir // a composite ExpressionNode otherwise.
756cdf0e10cSrcweir OperandStack maOperandStack;
757cdf0e10cSrcweir
758cdf0e10cSrcweir const EnhancedCustomShape2d* mpCustoShape;
759cdf0e10cSrcweir
760cdf0e10cSrcweir };
761cdf0e10cSrcweir
762cdf0e10cSrcweir typedef ::boost::shared_ptr< ParserContext > ParserContextSharedPtr;
763cdf0e10cSrcweir
764cdf0e10cSrcweir /** Generate apriori constant value
765cdf0e10cSrcweir */
766cdf0e10cSrcweir
767cdf0e10cSrcweir class ConstantFunctor
768cdf0e10cSrcweir {
769cdf0e10cSrcweir const double mnValue;
770cdf0e10cSrcweir ParserContextSharedPtr mpContext;
771cdf0e10cSrcweir
772cdf0e10cSrcweir public:
773cdf0e10cSrcweir
ConstantFunctor(double rValue,const ParserContextSharedPtr & rContext)774cdf0e10cSrcweir ConstantFunctor( double rValue, const ParserContextSharedPtr& rContext ) :
775cdf0e10cSrcweir mnValue( rValue ),
776cdf0e10cSrcweir mpContext( rContext )
777cdf0e10cSrcweir {
778cdf0e10cSrcweir }
operator ()(StringIteratorT,StringIteratorT) const779cdf0e10cSrcweir void operator()( StringIteratorT /*rFirst*/, StringIteratorT /*rSecond*/ ) const
780cdf0e10cSrcweir {
781cdf0e10cSrcweir mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( mnValue ) ) );
782cdf0e10cSrcweir }
783cdf0e10cSrcweir };
784cdf0e10cSrcweir
785cdf0e10cSrcweir /** Generate parse-dependent-but-then-constant value
786cdf0e10cSrcweir */
787cdf0e10cSrcweir class DoubleConstantFunctor
788cdf0e10cSrcweir {
789cdf0e10cSrcweir ParserContextSharedPtr mpContext;
790cdf0e10cSrcweir
791cdf0e10cSrcweir public:
DoubleConstantFunctor(const ParserContextSharedPtr & rContext)792cdf0e10cSrcweir DoubleConstantFunctor( const ParserContextSharedPtr& rContext ) :
793cdf0e10cSrcweir mpContext( rContext )
794cdf0e10cSrcweir {
795cdf0e10cSrcweir }
operator ()(double n) const796cdf0e10cSrcweir void operator()( double n ) const
797cdf0e10cSrcweir {
798cdf0e10cSrcweir mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( n ) ) );
799cdf0e10cSrcweir }
800cdf0e10cSrcweir };
801cdf0e10cSrcweir
802cdf0e10cSrcweir class EnumFunctor
803cdf0e10cSrcweir {
804cdf0e10cSrcweir const ExpressionFunct meFunct;
805cdf0e10cSrcweir double mnValue;
806cdf0e10cSrcweir ParserContextSharedPtr mpContext;
807cdf0e10cSrcweir
808cdf0e10cSrcweir public:
809cdf0e10cSrcweir
EnumFunctor(const ExpressionFunct eFunct,const ParserContextSharedPtr & rContext)810cdf0e10cSrcweir EnumFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext )
811cdf0e10cSrcweir : meFunct( eFunct )
812cdf0e10cSrcweir , mnValue( 0 )
813cdf0e10cSrcweir , mpContext( rContext )
814cdf0e10cSrcweir {
815cdf0e10cSrcweir }
operator ()(StringIteratorT rFirst,StringIteratorT rSecond) const816cdf0e10cSrcweir void operator()( StringIteratorT rFirst, StringIteratorT rSecond ) const
817cdf0e10cSrcweir {
818cdf0e10cSrcweir /*double nVal = mnValue;*/
819cdf0e10cSrcweir switch( meFunct )
820cdf0e10cSrcweir {
821cdf0e10cSrcweir case ENUM_FUNC_ADJUSTMENT :
822cdf0e10cSrcweir {
823cdf0e10cSrcweir rtl::OUString aVal( rFirst + 1, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
824cdf0e10cSrcweir mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new AdjustmentExpression( *mpContext->mpCustoShape, aVal.toInt32() ) ) );
825cdf0e10cSrcweir }
826cdf0e10cSrcweir break;
827cdf0e10cSrcweir case ENUM_FUNC_EQUATION :
828cdf0e10cSrcweir {
829cdf0e10cSrcweir rtl::OUString aVal( rFirst + 1, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
830cdf0e10cSrcweir mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new EquationExpression( *mpContext->mpCustoShape, aVal.toInt32() ) ) );
831cdf0e10cSrcweir }
832cdf0e10cSrcweir break;
833cdf0e10cSrcweir default:
834cdf0e10cSrcweir mpContext->maOperandStack.push( ExpressionNodeSharedPtr( new EnumValueExpression( *mpContext->mpCustoShape, meFunct ) ) );
835cdf0e10cSrcweir }
836cdf0e10cSrcweir }
837cdf0e10cSrcweir };
838cdf0e10cSrcweir
839cdf0e10cSrcweir class UnaryFunctionFunctor
840cdf0e10cSrcweir {
841cdf0e10cSrcweir const ExpressionFunct meFunct;
842cdf0e10cSrcweir ParserContextSharedPtr mpContext;
843cdf0e10cSrcweir
844cdf0e10cSrcweir public :
845cdf0e10cSrcweir
UnaryFunctionFunctor(const ExpressionFunct eFunct,const ParserContextSharedPtr & rContext)846cdf0e10cSrcweir UnaryFunctionFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext ) :
847cdf0e10cSrcweir meFunct( eFunct ),
848cdf0e10cSrcweir mpContext( rContext )
849cdf0e10cSrcweir {
850cdf0e10cSrcweir }
operator ()(StringIteratorT,StringIteratorT) const851cdf0e10cSrcweir void operator()( StringIteratorT, StringIteratorT ) const
852cdf0e10cSrcweir {
853cdf0e10cSrcweir ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );
854cdf0e10cSrcweir
855cdf0e10cSrcweir if( rNodeStack.size() < 1 )
856cdf0e10cSrcweir throw ParseError( "Not enough arguments for unary operator" );
857cdf0e10cSrcweir
858cdf0e10cSrcweir // retrieve arguments
859cdf0e10cSrcweir ExpressionNodeSharedPtr pArg( rNodeStack.top() );
860cdf0e10cSrcweir rNodeStack.pop();
861cdf0e10cSrcweir
862cdf0e10cSrcweir if( pArg->isConstant() ) // check for constness
863cdf0e10cSrcweir rNodeStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( UnaryFunctionExpression::getValue( meFunct, pArg ) ) ) );
864cdf0e10cSrcweir else // push complex node, that calcs the value on demand
865cdf0e10cSrcweir rNodeStack.push( ExpressionNodeSharedPtr( new UnaryFunctionExpression( meFunct, pArg ) ) );
866cdf0e10cSrcweir }
867cdf0e10cSrcweir };
868cdf0e10cSrcweir
869cdf0e10cSrcweir /** Implements a binary function over two ExpressionNodes
870cdf0e10cSrcweir
871cdf0e10cSrcweir @tpl Generator
872cdf0e10cSrcweir Generator functor, to generate an ExpressionNode of
873cdf0e10cSrcweir appropriate type
874cdf0e10cSrcweir
875cdf0e10cSrcweir */
876cdf0e10cSrcweir class BinaryFunctionFunctor
877cdf0e10cSrcweir {
878cdf0e10cSrcweir const ExpressionFunct meFunct;
879cdf0e10cSrcweir ParserContextSharedPtr mpContext;
880cdf0e10cSrcweir
881cdf0e10cSrcweir public:
882cdf0e10cSrcweir
BinaryFunctionFunctor(const ExpressionFunct eFunct,const ParserContextSharedPtr & rContext)883cdf0e10cSrcweir BinaryFunctionFunctor( const ExpressionFunct eFunct, const ParserContextSharedPtr& rContext ) :
884cdf0e10cSrcweir meFunct( eFunct ),
885cdf0e10cSrcweir mpContext( rContext )
886cdf0e10cSrcweir {
887cdf0e10cSrcweir }
888cdf0e10cSrcweir
operator ()(StringIteratorT,StringIteratorT) const889cdf0e10cSrcweir void operator()( StringIteratorT, StringIteratorT ) const
890cdf0e10cSrcweir {
891cdf0e10cSrcweir ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );
892cdf0e10cSrcweir
893cdf0e10cSrcweir if( rNodeStack.size() < 2 )
894cdf0e10cSrcweir throw ParseError( "Not enough arguments for binary operator" );
895cdf0e10cSrcweir
896cdf0e10cSrcweir // retrieve arguments
897cdf0e10cSrcweir ExpressionNodeSharedPtr pSecondArg( rNodeStack.top() );
898cdf0e10cSrcweir rNodeStack.pop();
899cdf0e10cSrcweir ExpressionNodeSharedPtr pFirstArg( rNodeStack.top() );
900cdf0e10cSrcweir rNodeStack.pop();
901cdf0e10cSrcweir
902cdf0e10cSrcweir // create combined ExpressionNode
903cdf0e10cSrcweir ExpressionNodeSharedPtr pNode = ExpressionNodeSharedPtr( new BinaryFunctionExpression( meFunct, pFirstArg, pSecondArg ) );
904cdf0e10cSrcweir // check for constness
905cdf0e10cSrcweir if( pFirstArg->isConstant() && pSecondArg->isConstant() ) // call the operator() at pNode, store result in constant value ExpressionNode.
906cdf0e10cSrcweir rNodeStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( (*pNode)() ) ) );
907cdf0e10cSrcweir else // push complex node, that calcs the value on demand
908cdf0e10cSrcweir rNodeStack.push( pNode );
909cdf0e10cSrcweir }
910cdf0e10cSrcweir };
911cdf0e10cSrcweir
912cdf0e10cSrcweir class IfFunctor
913cdf0e10cSrcweir {
914cdf0e10cSrcweir ParserContextSharedPtr mpContext;
915cdf0e10cSrcweir
916cdf0e10cSrcweir public :
917cdf0e10cSrcweir
IfFunctor(const ParserContextSharedPtr & rContext)918cdf0e10cSrcweir IfFunctor( const ParserContextSharedPtr& rContext ) :
919cdf0e10cSrcweir mpContext( rContext )
920cdf0e10cSrcweir {
921cdf0e10cSrcweir }
operator ()(StringIteratorT,StringIteratorT) const922cdf0e10cSrcweir void operator()( StringIteratorT, StringIteratorT ) const
923cdf0e10cSrcweir {
924cdf0e10cSrcweir ParserContext::OperandStack& rNodeStack( mpContext->maOperandStack );
925cdf0e10cSrcweir
926cdf0e10cSrcweir if( rNodeStack.size() < 3 )
927cdf0e10cSrcweir throw ParseError( "Not enough arguments for ternary operator" );
928cdf0e10cSrcweir
929cdf0e10cSrcweir // retrieve arguments
930cdf0e10cSrcweir ExpressionNodeSharedPtr pThirdArg( rNodeStack.top() );
931cdf0e10cSrcweir rNodeStack.pop();
932cdf0e10cSrcweir ExpressionNodeSharedPtr pSecondArg( rNodeStack.top() );
933cdf0e10cSrcweir rNodeStack.pop();
934cdf0e10cSrcweir ExpressionNodeSharedPtr pFirstArg( rNodeStack.top() );
935cdf0e10cSrcweir rNodeStack.pop();
936cdf0e10cSrcweir
937cdf0e10cSrcweir // create combined ExpressionNode
938cdf0e10cSrcweir ExpressionNodeSharedPtr pNode( new IfExpression( pFirstArg, pSecondArg, pThirdArg ) );
939cdf0e10cSrcweir // check for constness
940cdf0e10cSrcweir if( pFirstArg->isConstant() && pSecondArg->isConstant() && pThirdArg->isConstant() )
941cdf0e10cSrcweir rNodeStack.push( ExpressionNodeSharedPtr( new ConstantValueExpression( (*pNode)() ) ) ); // call the operator() at pNode, store result in constant value ExpressionNode.
942cdf0e10cSrcweir else
943cdf0e10cSrcweir rNodeStack.push( pNode ); // push complex node, that calcs the value on demand
944cdf0e10cSrcweir }
945cdf0e10cSrcweir };
946cdf0e10cSrcweir
947cdf0e10cSrcweir // Workaround for MSVC compiler anomaly (stack trashing)
948cdf0e10cSrcweir //
949cdf0e10cSrcweir // The default ureal_parser_policies implementation of parse_exp
950cdf0e10cSrcweir // triggers a really weird error in MSVC7 (Version 13.00.9466), in
951cdf0e10cSrcweir // that the real_parser_impl::parse_main() call of parse_exp()
952cdf0e10cSrcweir // overwrites the frame pointer _on the stack_ (EBP of the calling
953cdf0e10cSrcweir // function gets overwritten while lying on the stack).
954cdf0e10cSrcweir //
955cdf0e10cSrcweir // For the time being, our parser thus can only read the 1.0E10
956cdf0e10cSrcweir // notation, not the 1.0e10 one.
957cdf0e10cSrcweir //
958cdf0e10cSrcweir // TODO(F1): Also handle the 1.0e10 case here.
959cdf0e10cSrcweir template< typename T > struct custom_real_parser_policies : public ::boost::spirit::ureal_parser_policies<T>
960cdf0e10cSrcweir {
961cdf0e10cSrcweir template< typename ScannerT >
962cdf0e10cSrcweir static typename ::boost::spirit::parser_result< ::boost::spirit::chlit<>, ScannerT >::type
parse_exp__anoneb3093d20111::custom_real_parser_policies963cdf0e10cSrcweir parse_exp(ScannerT& scan)
964cdf0e10cSrcweir {
965cdf0e10cSrcweir // as_lower_d somehow breaks MSVC7
966cdf0e10cSrcweir return ::boost::spirit::ch_p('E').parse(scan);
967cdf0e10cSrcweir }
968cdf0e10cSrcweir };
969cdf0e10cSrcweir
970cdf0e10cSrcweir /* This class implements the following grammar (more or
971cdf0e10cSrcweir less literally written down below, only slightly
972cdf0e10cSrcweir obfuscated by the parser actions):
973cdf0e10cSrcweir
974cdf0e10cSrcweir identifier = '$'|'pi'|'e'|'X'|'Y'|'Width'|'Height'
975cdf0e10cSrcweir
976cdf0e10cSrcweir function = 'abs'|'sqrt'|'sin'|'cos'|'tan'|'atan'|'acos'|'asin'|'exp'|'log'
977cdf0e10cSrcweir
978cdf0e10cSrcweir basic_expression =
979cdf0e10cSrcweir number |
980cdf0e10cSrcweir identifier |
981cdf0e10cSrcweir function '(' additive_expression ')' |
982cdf0e10cSrcweir '(' additive_expression ')'
983cdf0e10cSrcweir
984cdf0e10cSrcweir unary_expression =
985cdf0e10cSrcweir '-' basic_expression |
986cdf0e10cSrcweir basic_expression
987cdf0e10cSrcweir
988cdf0e10cSrcweir multiplicative_expression =
989cdf0e10cSrcweir unary_expression ( ( '*' unary_expression )* |
990cdf0e10cSrcweir ( '/' unary_expression )* )
991cdf0e10cSrcweir
992cdf0e10cSrcweir additive_expression =
993cdf0e10cSrcweir multiplicative_expression ( ( '+' multiplicative_expression )* |
994cdf0e10cSrcweir ( '-' multiplicative_expression )* )
995cdf0e10cSrcweir
996cdf0e10cSrcweir */
997cdf0e10cSrcweir
998cdf0e10cSrcweir class ExpressionGrammar : public ::boost::spirit::grammar< ExpressionGrammar >
999cdf0e10cSrcweir {
1000cdf0e10cSrcweir public:
1001cdf0e10cSrcweir /** Create an arithmetic expression grammar
1002cdf0e10cSrcweir
1003cdf0e10cSrcweir @param rParserContext
1004cdf0e10cSrcweir Contains context info for the parser
1005cdf0e10cSrcweir */
ExpressionGrammar(const ParserContextSharedPtr & rParserContext)1006cdf0e10cSrcweir ExpressionGrammar( const ParserContextSharedPtr& rParserContext ) :
1007cdf0e10cSrcweir mpParserContext( rParserContext )
1008cdf0e10cSrcweir {
1009cdf0e10cSrcweir }
1010cdf0e10cSrcweir
1011cdf0e10cSrcweir template< typename ScannerT > class definition
1012cdf0e10cSrcweir {
1013cdf0e10cSrcweir public:
1014cdf0e10cSrcweir // grammar definition
definition(const ExpressionGrammar & self)1015cdf0e10cSrcweir definition( const ExpressionGrammar& self )
1016cdf0e10cSrcweir {
1017cdf0e10cSrcweir using ::boost::spirit::str_p;
1018cdf0e10cSrcweir using ::boost::spirit::range_p;
1019cdf0e10cSrcweir using ::boost::spirit::lexeme_d;
1020cdf0e10cSrcweir using ::boost::spirit::real_parser;
1021cdf0e10cSrcweir using ::boost::spirit::chseq_p;
1022cdf0e10cSrcweir
1023cdf0e10cSrcweir identifier =
1024cdf0e10cSrcweir str_p( "pi" )[ EnumFunctor(ENUM_FUNC_PI, self.getContext() ) ]
1025cdf0e10cSrcweir | str_p( "left" )[ EnumFunctor(ENUM_FUNC_LEFT, self.getContext() ) ]
1026cdf0e10cSrcweir | str_p( "top" )[ EnumFunctor(ENUM_FUNC_TOP, self.getContext() ) ]
1027cdf0e10cSrcweir | str_p( "right" )[ EnumFunctor(ENUM_FUNC_RIGHT, self.getContext() ) ]
1028cdf0e10cSrcweir | str_p( "bottom" )[ EnumFunctor(ENUM_FUNC_BOTTOM, self.getContext() ) ]
1029cdf0e10cSrcweir | str_p( "xstretch" )[ EnumFunctor(ENUM_FUNC_XSTRETCH, self.getContext() ) ]
1030cdf0e10cSrcweir | str_p( "ystretch" )[ EnumFunctor(ENUM_FUNC_YSTRETCH, self.getContext() ) ]
1031cdf0e10cSrcweir | str_p( "hasstroke" )[ EnumFunctor(ENUM_FUNC_HASSTROKE, self.getContext() ) ]
1032cdf0e10cSrcweir | str_p( "hasfill" )[ EnumFunctor(ENUM_FUNC_HASFILL, self.getContext() ) ]
1033cdf0e10cSrcweir | str_p( "width" )[ EnumFunctor(ENUM_FUNC_WIDTH, self.getContext() ) ]
1034cdf0e10cSrcweir | str_p( "height" )[ EnumFunctor(ENUM_FUNC_HEIGHT, self.getContext() ) ]
1035cdf0e10cSrcweir | str_p( "logwidth" )[ EnumFunctor(ENUM_FUNC_LOGWIDTH, self.getContext() ) ]
1036cdf0e10cSrcweir | str_p( "logheight" )[ EnumFunctor(ENUM_FUNC_LOGHEIGHT, self.getContext() ) ]
1037cdf0e10cSrcweir ;
1038cdf0e10cSrcweir
1039cdf0e10cSrcweir unaryFunction =
1040cdf0e10cSrcweir (str_p( "abs" ) >> '(' >> additiveExpression >> ')' )[ UnaryFunctionFunctor( UNARY_FUNC_ABS, self.getContext()) ]
1041cdf0e10cSrcweir | (str_p( "sqrt" ) >> '(' >> additiveExpression >> ')' )[ UnaryFunctionFunctor( UNARY_FUNC_SQRT, self.getContext()) ]
1042cdf0e10cSrcweir | (str_p( "sin" ) >> '(' >> additiveExpression >> ')' )[ UnaryFunctionFunctor( UNARY_FUNC_SIN, self.getContext()) ]
1043cdf0e10cSrcweir | (str_p( "cos" ) >> '(' >> additiveExpression >> ')' )[ UnaryFunctionFunctor( UNARY_FUNC_COS, self.getContext()) ]
1044cdf0e10cSrcweir | (str_p( "tan" ) >> '(' >> additiveExpression >> ')' )[ UnaryFunctionFunctor( UNARY_FUNC_TAN, self.getContext()) ]
1045cdf0e10cSrcweir | (str_p( "atan" ) >> '(' >> additiveExpression >> ')' )[ UnaryFunctionFunctor( UNARY_FUNC_ATAN, self.getContext()) ]
1046cdf0e10cSrcweir ;
1047cdf0e10cSrcweir
1048cdf0e10cSrcweir binaryFunction =
1049cdf0e10cSrcweir (str_p( "min" ) >> '(' >> additiveExpression >> ',' >> additiveExpression >> ')' )[ BinaryFunctionFunctor( BINARY_FUNC_MIN, self.getContext()) ]
1050cdf0e10cSrcweir | (str_p( "max" ) >> '(' >> additiveExpression >> ',' >> additiveExpression >> ')' )[ BinaryFunctionFunctor( BINARY_FUNC_MAX, self.getContext()) ]
1051cdf0e10cSrcweir | (str_p( "atan2") >> '(' >> additiveExpression >> ',' >> additiveExpression >> ')' )[ BinaryFunctionFunctor( BINARY_FUNC_ATAN2,self.getContext()) ]
1052cdf0e10cSrcweir ;
1053cdf0e10cSrcweir
1054cdf0e10cSrcweir ternaryFunction =
1055cdf0e10cSrcweir (str_p( "if" ) >> '(' >> additiveExpression >> ',' >> additiveExpression >> ',' >> additiveExpression >> ')' )[ IfFunctor( self.getContext() ) ]
1056cdf0e10cSrcweir ;
1057cdf0e10cSrcweir
1058cdf0e10cSrcweir funcRef_decl =
1059cdf0e10cSrcweir lexeme_d[ +( range_p('a','z') | range_p('A','Z') | range_p('0','9') ) ];
1060cdf0e10cSrcweir
1061cdf0e10cSrcweir functionReference =
1062cdf0e10cSrcweir (str_p( "?" ) >> funcRef_decl )[ EnumFunctor( ENUM_FUNC_EQUATION, self.getContext() ) ];
1063cdf0e10cSrcweir
1064cdf0e10cSrcweir modRef_decl =
1065cdf0e10cSrcweir lexeme_d[ +( range_p('0','9') ) ];
1066cdf0e10cSrcweir
1067cdf0e10cSrcweir modifierReference =
1068cdf0e10cSrcweir (str_p( "$" ) >> modRef_decl )[ EnumFunctor( ENUM_FUNC_ADJUSTMENT, self.getContext() ) ];
1069cdf0e10cSrcweir
1070cdf0e10cSrcweir basicExpression =
1071cdf0e10cSrcweir real_parser<double, custom_real_parser_policies<double> >()[ DoubleConstantFunctor(self.getContext()) ]
1072cdf0e10cSrcweir | identifier
1073cdf0e10cSrcweir | functionReference
1074cdf0e10cSrcweir | modifierReference
1075cdf0e10cSrcweir | unaryFunction
1076cdf0e10cSrcweir | binaryFunction
1077cdf0e10cSrcweir | ternaryFunction
1078cdf0e10cSrcweir | '(' >> additiveExpression >> ')'
1079cdf0e10cSrcweir ;
1080cdf0e10cSrcweir
1081cdf0e10cSrcweir unaryExpression =
1082cdf0e10cSrcweir ('-' >> basicExpression)[ UnaryFunctionFunctor( UNARY_FUNC_NEG, self.getContext()) ]
1083cdf0e10cSrcweir | basicExpression
1084cdf0e10cSrcweir ;
1085cdf0e10cSrcweir
1086cdf0e10cSrcweir multiplicativeExpression =
1087cdf0e10cSrcweir unaryExpression
1088cdf0e10cSrcweir >> *( ('*' >> unaryExpression)[ BinaryFunctionFunctor( BINARY_FUNC_MUL, self.getContext()) ]
1089cdf0e10cSrcweir | ('/' >> unaryExpression)[ BinaryFunctionFunctor( BINARY_FUNC_DIV, self.getContext()) ]
1090cdf0e10cSrcweir )
1091cdf0e10cSrcweir ;
1092cdf0e10cSrcweir
1093cdf0e10cSrcweir additiveExpression =
1094cdf0e10cSrcweir multiplicativeExpression
1095cdf0e10cSrcweir >> *( ('+' >> multiplicativeExpression)[ BinaryFunctionFunctor( BINARY_FUNC_PLUS, self.getContext()) ]
1096cdf0e10cSrcweir | ('-' >> multiplicativeExpression)[ BinaryFunctionFunctor( BINARY_FUNC_MINUS, self.getContext()) ]
1097cdf0e10cSrcweir )
1098cdf0e10cSrcweir ;
1099cdf0e10cSrcweir
1100cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(additiveExpression);
1101cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(multiplicativeExpression);
1102cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(unaryExpression);
1103cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(basicExpression);
1104cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(unaryFunction);
1105cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(binaryFunction);
1106cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(ternaryFunction);
1107cdf0e10cSrcweir BOOST_SPIRIT_DEBUG_RULE(identifier);
1108cdf0e10cSrcweir }
1109cdf0e10cSrcweir
start() const1110cdf0e10cSrcweir const ::boost::spirit::rule< ScannerT >& start() const
1111cdf0e10cSrcweir {
1112cdf0e10cSrcweir return additiveExpression;
1113cdf0e10cSrcweir }
1114cdf0e10cSrcweir
1115cdf0e10cSrcweir private:
1116cdf0e10cSrcweir // the constituents of the Spirit arithmetic expression grammar.
1117cdf0e10cSrcweir // For the sake of readability, without 'ma' prefix.
1118cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > additiveExpression;
1119cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > multiplicativeExpression;
1120cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > unaryExpression;
1121cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > basicExpression;
1122cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > unaryFunction;
1123cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > binaryFunction;
1124cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > ternaryFunction;
1125cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > funcRef_decl;
1126cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > functionReference;
1127cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > modRef_decl;
1128cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > modifierReference;
1129cdf0e10cSrcweir ::boost::spirit::rule< ScannerT > identifier;
1130cdf0e10cSrcweir };
1131cdf0e10cSrcweir
getContext() const1132cdf0e10cSrcweir const ParserContextSharedPtr& getContext() const
1133cdf0e10cSrcweir {
1134cdf0e10cSrcweir return mpParserContext;
1135cdf0e10cSrcweir }
1136cdf0e10cSrcweir
1137cdf0e10cSrcweir private:
1138cdf0e10cSrcweir ParserContextSharedPtr mpParserContext; // might get modified during parsing
1139cdf0e10cSrcweir };
1140cdf0e10cSrcweir
1141cdf0e10cSrcweir #ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
getParserContext()1142cdf0e10cSrcweir const ParserContextSharedPtr& getParserContext()
1143cdf0e10cSrcweir {
1144cdf0e10cSrcweir static ParserContextSharedPtr lcl_parserContext( new ParserContext() );
1145cdf0e10cSrcweir
1146cdf0e10cSrcweir // clear node stack (since we reuse the static object, that's
1147cdf0e10cSrcweir // the whole point here)
1148cdf0e10cSrcweir while( !lcl_parserContext->maOperandStack.empty() )
1149cdf0e10cSrcweir lcl_parserContext->maOperandStack.pop();
1150cdf0e10cSrcweir
1151cdf0e10cSrcweir return lcl_parserContext;
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir #endif
1154cdf0e10cSrcweir
1155cdf0e10cSrcweir }
1156cdf0e10cSrcweir
1157cdf0e10cSrcweir namespace EnhancedCustomShape {
1158cdf0e10cSrcweir
1159cdf0e10cSrcweir
1160cdf0e10cSrcweir
parseFunction(const::rtl::OUString & rFunction,const EnhancedCustomShape2d & rCustoShape)1161cdf0e10cSrcweir ExpressionNodeSharedPtr FunctionParser::parseFunction( const ::rtl::OUString& rFunction, const EnhancedCustomShape2d& rCustoShape )
1162cdf0e10cSrcweir {
1163cdf0e10cSrcweir // TODO(Q1): Check if a combination of the RTL_UNICODETOTEXT_FLAGS_*
1164cdf0e10cSrcweir // gives better conversion robustness here (we might want to map space
1165cdf0e10cSrcweir // etc. to ASCII space here)
1166cdf0e10cSrcweir const ::rtl::OString& rAsciiFunction(
1167cdf0e10cSrcweir rtl::OUStringToOString( rFunction, RTL_TEXTENCODING_ASCII_US ) );
1168cdf0e10cSrcweir
1169cdf0e10cSrcweir StringIteratorT aStart( rAsciiFunction.getStr() );
1170cdf0e10cSrcweir StringIteratorT aEnd( rAsciiFunction.getStr()+rAsciiFunction.getLength() );
1171cdf0e10cSrcweir
1172cdf0e10cSrcweir ParserContextSharedPtr pContext;
1173cdf0e10cSrcweir
1174cdf0e10cSrcweir #ifdef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
1175cdf0e10cSrcweir // static parser context, because the actual
1176cdf0e10cSrcweir // Spirit parser is also a static object
1177cdf0e10cSrcweir pContext = getParserContext();
1178cdf0e10cSrcweir #else
1179cdf0e10cSrcweir pContext.reset( new ParserContext() );
1180cdf0e10cSrcweir #endif
1181cdf0e10cSrcweir pContext->mpCustoShape = &rCustoShape;
1182cdf0e10cSrcweir
1183cdf0e10cSrcweir ExpressionGrammar aExpressionGrammer( pContext );
1184cdf0e10cSrcweir const ::boost::spirit::parse_info<StringIteratorT> aParseInfo(
1185cdf0e10cSrcweir ::boost::spirit::parse( aStart,
1186cdf0e10cSrcweir aEnd,
1187cdf0e10cSrcweir aExpressionGrammer >> ::boost::spirit::end_p,
1188cdf0e10cSrcweir ::boost::spirit::space_p ) );
1189cdf0e10cSrcweir OSL_DEBUG_ONLY(::std::cout.flush()); // needed to keep stdout and cout in sync
1190cdf0e10cSrcweir
1191cdf0e10cSrcweir
1192cdf0e10cSrcweir
1193cdf0e10cSrcweir // input fully congested by the parser?
1194cdf0e10cSrcweir if( !aParseInfo.full )
1195cdf0e10cSrcweir throw ParseError( "EnhancedCustomShapeFunctionParser::parseFunction(): string not fully parseable" );
1196cdf0e10cSrcweir
1197cdf0e10cSrcweir // parser's state stack now must contain exactly _one_ ExpressionNode,
1198cdf0e10cSrcweir // which represents our formula.
1199cdf0e10cSrcweir if( pContext->maOperandStack.size() != 1 )
1200cdf0e10cSrcweir throw ParseError( "EnhancedCustomShapeFunctionParser::parseFunction(): incomplete or empty expression" );
1201cdf0e10cSrcweir
1202cdf0e10cSrcweir
1203cdf0e10cSrcweir return pContext->maOperandStack.top();
1204cdf0e10cSrcweir }
1205cdf0e10cSrcweir
1206cdf0e10cSrcweir
1207cdf0e10cSrcweir }
1208cdf0e10cSrcweir
1209