Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "oox/drawingml/customshapegeometry.hxx"
21 :
22 : #include <com/sun/star/xml/sax/FastToken.hpp>
23 : #include <comphelper/stl_types.hxx>
24 : #include <boost/unordered_map.hpp>
25 : #include "oox/helper/helper.hxx"
26 : #include "oox/helper/attributelist.hxx"
27 : #include "oox/helper/propertymap.hxx"
28 :
29 : using namespace ::oox::core;
30 : using namespace ::com::sun::star::uno;
31 : using namespace ::com::sun::star::beans;
32 : using namespace ::com::sun::star::drawing;
33 : using namespace ::com::sun::star::xml::sax;
34 :
35 : namespace oox { namespace drawingml {
36 :
37 : enum FormularCommand
38 : {
39 : FC_MULDIV = 0,
40 : FC_PLUSMINUS,
41 : FC_PLUSDIV,
42 : FC_IFELSE,
43 : FC_IFELSE1,
44 : FC_ABS,
45 : FC_AT2,
46 : FC_CAT2,
47 : FC_COS,
48 : FC_MAX,
49 : FC_MIN,
50 : FC_MOD,
51 : FC_PIN,
52 : FC_SAT2,
53 : FC_SIN,
54 : FC_SQRT,
55 : FC_TAN,
56 : FC_VAL,
57 : FC_LAST
58 : };
59 : struct FormularCommandNameTable
60 : {
61 : const char* pS;
62 : FormularCommand pE;
63 : };
64 : static FormularCommandNameTable pFormularCommandNameTable[] =
65 : {
66 : { "*/", FC_MULDIV },
67 : { "+-", FC_PLUSMINUS },
68 : { "+/", FC_PLUSDIV },
69 : { "ifelse", FC_IFELSE },
70 : { "?:", FC_IFELSE1 },
71 : { "abs", FC_ABS },
72 : { "at2", FC_AT2 },
73 : { "cat2", FC_CAT2 },
74 : { "cos", FC_COS },
75 : { "max", FC_MAX },
76 : { "min", FC_MIN },
77 : { "mod", FC_MOD },
78 : { "pin", FC_PIN },
79 : { "sat2", FC_SAT2 },
80 : { "sin", FC_SIN },
81 : { "sqrt", FC_SQRT },
82 : { "tan", FC_TAN },
83 : { "val", FC_VAL }
84 :
85 : };
86 : typedef boost::unordered_map< OUString, FormularCommand, OUStringHash, comphelper::UStringEqual > FormulaCommandHMap;
87 :
88 : static const FormulaCommandHMap* pCommandHashMap;
89 :
90 : //
91 475 : OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
92 : {
93 475 : OUString aRet;
94 475 : switch( rParameter.Type )
95 : {
96 : case EnhancedCustomShapeParameterType::NORMAL :
97 : {
98 329 : if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
99 : {
100 0 : double fValue = 0.0;
101 0 : if ( rParameter.Value >>= fValue )
102 0 : aRet = OUString::valueOf( fValue );
103 : }
104 : else
105 : {
106 329 : sal_Int32 nValue = 0;
107 329 : if ( rParameter.Value >>= nValue )
108 329 : aRet = OUString::valueOf( nValue );
109 : }
110 : }
111 329 : break;
112 : case EnhancedCustomShapeParameterType::EQUATION :
113 : {
114 0 : if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
115 : {
116 : sal_Int32 nFormulaIndex;
117 0 : if ( rParameter.Value >>= nFormulaIndex )
118 : {
119 0 : aRet = "?"
120 0 : + OUString::valueOf( nFormulaIndex )
121 0 : + " ";
122 : }
123 : }
124 : else
125 : {
126 : // ups... we should have an index here and not the formula name
127 : }
128 : }
129 0 : break;
130 : case EnhancedCustomShapeParameterType::ADJUSTMENT :
131 : {
132 0 : if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
133 : {
134 : sal_Int32 nAdjustmentIndex;
135 0 : if ( rParameter.Value >>= nAdjustmentIndex )
136 : {
137 0 : aRet = "$"
138 0 : + OUString::valueOf( nAdjustmentIndex )
139 0 : + " ";
140 : }
141 : }
142 : else
143 : {
144 : // ups... we should have an index here and not the formula name
145 : }
146 : }
147 0 : break;
148 : case EnhancedCustomShapeParameterType::LEFT :
149 : {
150 0 : const OUString sLeft( "left" );
151 0 : aRet = sLeft;
152 : }
153 0 : break;
154 : case EnhancedCustomShapeParameterType::TOP :
155 : {
156 0 : const OUString sTop( "top" );
157 0 : aRet = sTop;
158 : }
159 0 : break;
160 : case EnhancedCustomShapeParameterType::RIGHT :
161 : {
162 0 : const OUString sRight( "right" );
163 0 : aRet = sRight;
164 : }
165 0 : break;
166 : case EnhancedCustomShapeParameterType::BOTTOM :
167 : {
168 0 : const OUString sBottom( "bottom" );
169 0 : aRet = sBottom;
170 : }
171 0 : break;
172 : case EnhancedCustomShapeParameterType::XSTRETCH :
173 : {
174 0 : const OUString sXStretch( "xstretch" );
175 0 : aRet = sXStretch;
176 : }
177 0 : break;
178 : case EnhancedCustomShapeParameterType::YSTRETCH :
179 : {
180 0 : const OUString sYStretch( "ystretch" );
181 0 : aRet = sYStretch;
182 : }
183 0 : break;
184 : case EnhancedCustomShapeParameterType::HASSTROKE :
185 : {
186 0 : const OUString sHasStroke( "hasstroke" );
187 0 : aRet = sHasStroke;
188 : }
189 0 : break;
190 : case EnhancedCustomShapeParameterType::HASFILL :
191 : {
192 0 : const OUString sHasFill( "hasfill" );
193 0 : aRet = sHasFill;
194 : }
195 0 : break;
196 : case EnhancedCustomShapeParameterType::WIDTH :
197 : {
198 0 : const OUString sWidth( "width" );
199 0 : aRet = sWidth;
200 : }
201 0 : break;
202 : case EnhancedCustomShapeParameterType::HEIGHT :
203 : {
204 0 : const OUString sHeight( "height" );
205 0 : aRet = sHeight;
206 : }
207 0 : break;
208 : case EnhancedCustomShapeParameterType::LOGWIDTH :
209 : {
210 73 : const OUString sLogWidth( "logwidth" );
211 73 : aRet = sLogWidth;
212 : }
213 73 : break;
214 : case EnhancedCustomShapeParameterType::LOGHEIGHT :
215 : {
216 73 : const OUString sLogHeight( "logheight" );
217 73 : aRet = sLogHeight;
218 : }
219 73 : break;
220 : }
221 475 : return aRet;
222 : }
223 :
224 : // ---------------------------------------------------------------------
225 :
226 600 : static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const OUString& rValue, sal_Bool bNoSymbols = sal_True )
227 : {
228 600 : com::sun::star::drawing::EnhancedCustomShapeParameter aRet;
229 600 : if ( !rValue.isEmpty() )
230 : {
231 600 : sal_Bool bConstant = sal_True;
232 600 : sal_Int32 nConstant = -1;
233 600 : sal_Int32 nIntVal = 0;
234 :
235 : // first check if its a constant value
236 600 : switch( AttributeConversion::decodeToken( rValue ) )
237 : {
238 0 : case XML_3cd4 : nConstant = 270 * 60000; break;
239 0 : case XML_3cd8 : nConstant = 135 * 60000; break;
240 0 : case XML_5cd8 : nConstant = 225 * 60000; break;
241 0 : case XML_7cd8 : nConstant = 315 * 60000; break;
242 0 : case XML_cd2 : nConstant = 180 * 60000; break;
243 0 : case XML_cd3 : nConstant = 120 * 60000; break;
244 0 : case XML_cd4 : nConstant = 90 * 60000; break;
245 0 : case XML_cd8 : nConstant = 45 * 60000; break;
246 :
247 : case XML_b : // variable height of the shape defined in spPr
248 : case XML_h :
249 : {
250 76 : if ( bNoSymbols )
251 : {
252 3 : CustomShapeGuide aGuide;
253 3 : aGuide.maName = rValue;
254 3 : aGuide.maFormula = "logheight" ;
255 :
256 3 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
257 3 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
258 : }
259 : else
260 73 : aRet.Type = EnhancedCustomShapeParameterType::LOGHEIGHT; // TODO: HEIGHT needs to be implemented
261 : }
262 76 : break;
263 :
264 :
265 : case XML_hd10 : // !!PASSTHROUGH INTENDED
266 0 : nIntVal += 2; // */ h 1.0 10.0
267 : case XML_hd8 : // */ h 1.0 8.0
268 0 : nIntVal += 2;
269 : case XML_hd6 : // */ h 1.0 6.0
270 0 : nIntVal++;
271 : case XML_hd5 : // */ h 1.0 5.0
272 0 : nIntVal++;
273 : case XML_hd4 : // */ h 1.0 4.0
274 0 : nIntVal++;
275 : case XML_hd3 : // */ h 1.0 3.0
276 0 : nIntVal++;
277 : case XML_hd2 : // */ h 1.0 2.0
278 : case XML_vc : // */ h 1.0 2.0
279 : {
280 0 : nIntVal += 2;
281 :
282 0 : CustomShapeGuide aGuide;
283 0 : aGuide.maName = rValue;
284 0 : aGuide.maFormula = "logheight/" + OUString::valueOf( nIntVal );
285 :
286 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
287 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
288 : }
289 0 : break;
290 :
291 : case XML_t :
292 : case XML_l :
293 : {
294 2 : nConstant = 0;
295 2 : aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
296 : }
297 2 : break;
298 :
299 : case XML_ls : // longest side: max w h
300 : {
301 0 : CustomShapeGuide aGuide;
302 0 : aGuide.maName = rValue;
303 0 : aGuide.maFormula = "max(logwidth,logheight)";
304 :
305 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
306 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
307 : }
308 0 : break;
309 : case XML_ss : // shortest side: min w h
310 : {
311 0 : CustomShapeGuide aGuide;
312 0 : aGuide.maName = rValue;
313 0 : aGuide.maFormula = "min(logwidth,logheight)";
314 :
315 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
316 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
317 : }
318 0 : break;
319 : case XML_ssd32 : // */ ss 1.0 32.0
320 0 : nIntVal += 16;
321 : case XML_ssd16 : // */ ss 1.0 16.0
322 0 : nIntVal += 8;
323 : case XML_ssd8 : // */ ss 1.0 8.0
324 0 : nIntVal += 2;
325 : case XML_ssd6 : // */ ss 1.0 6.0
326 0 : nIntVal += 2;
327 : case XML_ssd4 : // */ ss 1.0 4.0
328 0 : nIntVal += 2;
329 : case XML_ssd2 : // */ ss 1.0 2.0
330 : {
331 0 : nIntVal += 2;
332 :
333 0 : CustomShapeGuide aGuide;
334 0 : aGuide.maName = rValue;
335 0 : aGuide.maFormula = "min(logwidth,logheight)/" + OUString::valueOf( nIntVal );
336 :
337 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
338 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
339 : }
340 0 : break;
341 :
342 : case XML_r : // variable width of the shape defined in spPr
343 : case XML_w :
344 : {
345 76 : if ( bNoSymbols )
346 : {
347 3 : CustomShapeGuide aGuide;
348 3 : aGuide.maName = rValue;
349 3 : aGuide.maFormula = "logwidth" ;
350 :
351 3 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
352 3 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
353 : }
354 : else
355 73 : aRet.Type = EnhancedCustomShapeParameterType::LOGWIDTH;
356 : }
357 76 : break;
358 :
359 : case XML_wd32 : // */ w 1.0 32.0
360 0 : nIntVal += 20;
361 : case XML_wd12 : // */ w 1.0 12.0
362 0 : nIntVal += 2;
363 : case XML_wd10 : // */ w 1.0 10.0
364 0 : nIntVal += 2;
365 : case XML_wd8 : // */ w 1.0 8.0
366 0 : nIntVal += 2;
367 : case XML_wd6 : // */ w 1.0 6.0
368 0 : nIntVal++;
369 : case XML_wd5 : // */ w 1.0 5.0
370 0 : nIntVal++;
371 : case XML_wd4 : // */ w 1.0 4.0
372 0 : nIntVal++;
373 : case XML_wd3 : // */ w 1.0 3.0
374 0 : nIntVal++;
375 : case XML_hc : // */ w 1.0 2.0
376 : case XML_wd2 : // */ w 1.0 2.0
377 : {
378 0 : nIntVal += 2;
379 :
380 0 : CustomShapeGuide aGuide;
381 0 : aGuide.maName = rValue;
382 0 : aGuide.maFormula = "logwidth/" + OUString::valueOf( nIntVal );
383 :
384 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
385 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
386 : }
387 0 : break;
388 :
389 : default:
390 446 : bConstant = sal_False;
391 446 : break;
392 : }
393 600 : if ( bConstant )
394 : {
395 154 : if (nConstant != -1) {
396 2 : aRet.Value = Any( nConstant );
397 2 : aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
398 : }
399 : }
400 : else
401 : {
402 446 : sal_Unicode n = rValue[ 0 ];
403 446 : if ( ( n == '+' ) || ( n == '-' ) )
404 : {
405 7 : if ( rValue.getLength() > 1 )
406 7 : n = rValue[ 1 ];
407 : }
408 446 : if ( ( n >= '0' ) && ( n <= '9' ) )
409 : { // seems to be a ST_Coordinate
410 412 : aRet.Value = Any( (sal_Int32)(rValue.toInt32() ) );
411 412 : aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
412 : }
413 : else
414 : {
415 34 : sal_Int32 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getAdjustmentGuideList(), rValue );
416 34 : if ( nGuideIndex >= 0 )
417 : {
418 0 : aRet.Value = Any( nGuideIndex );
419 0 : aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
420 : }
421 : else
422 : {
423 34 : nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), rValue );
424 34 : if ( nGuideIndex >= 0 )
425 : {
426 34 : aRet.Value = Any( nGuideIndex );
427 34 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
428 : }
429 : else
430 : {
431 : OSL_TRACE("error: unhandled value '%s'", OUStringToOString( rValue, RTL_TEXTENCODING_ASCII_US ).getStr());
432 0 : aRet.Value = Any( rValue );
433 : }
434 : }
435 : }
436 : }
437 : }
438 600 : return aRet;
439 : }
440 :
441 : // ---------------------------------------------------------------------
442 : // CT_GeomGuideList
443 290 : class GeomGuideListContext : public ContextHandler2
444 : {
445 : public:
446 : GeomGuideListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList );
447 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
448 :
449 : protected:
450 : std::vector< CustomShapeGuide >& mrGuideList;
451 : CustomShapeProperties& mrCustomShapeProperties;
452 : };
453 :
454 145 : GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList )
455 : : ContextHandler2( rParent )
456 : , mrGuideList( rGuideList )
457 145 : , mrCustomShapeProperties( rCustomShapeProperties )
458 : {
459 145 : }
460 :
461 167 : static OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, const OUString& rSource )
462 : {
463 167 : if ( !pCommandHashMap )
464 : {
465 1 : FormulaCommandHMap* pHM = new FormulaCommandHMap();
466 19 : for( sal_Int32 i = 0; i < FC_LAST; i++ )
467 18 : (*pHM)[ OUString::createFromAscii( pFormularCommandNameTable[ i ].pS ) ] = pFormularCommandNameTable[ i ].pE;
468 1 : pCommandHashMap = pHM;
469 : }
470 :
471 167 : std::vector< OUString > aTokens;
472 167 : sal_Int32 nIndex = 0;
473 642 : do
474 : {
475 642 : OUString aToken( rSource.getToken( 0, ' ', nIndex ) );
476 642 : if ( !aToken.isEmpty() )
477 642 : aTokens.push_back( aToken );
478 : }
479 642 : while ( nIndex >= 0 );
480 :
481 167 : OUString aEquation;
482 167 : if ( !aTokens.empty() )
483 : {
484 167 : sal_Int32 i, nParameters = aTokens.size() - 1;
485 167 : if ( nParameters > 3 )
486 0 : nParameters = 3;
487 :
488 668 : OUString sParameters[ 3 ];
489 :
490 642 : for ( i = 0; i < nParameters; i++ )
491 475 : sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], sal_False ) );
492 :
493 167 : const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
494 167 : if ( aIter != pCommandHashMap->end() )
495 : {
496 167 : switch( aIter->second )
497 : {
498 : case FC_MULDIV :
499 : {
500 154 : if ( nParameters == 3 )
501 616 : aEquation = sParameters[ 0 ] + "*" + sParameters[ 1 ]
502 462 : + "/" + sParameters[ 2 ];
503 : }
504 154 : break;
505 : case FC_PLUSMINUS :
506 : {
507 0 : if ( nParameters == 3 )
508 0 : aEquation = sParameters[ 0 ] + "+" + sParameters[ 1 ]
509 0 : + "-" + sParameters[ 2 ];
510 : }
511 0 : break;
512 : case FC_PLUSDIV :
513 : {
514 0 : if ( nParameters == 3 )
515 0 : aEquation = "(" + sParameters[ 0 ] + "+"
516 0 : + sParameters[ 1 ] + ")/" + sParameters[ 2 ];
517 : }
518 0 : break;
519 : case FC_IFELSE :
520 : case FC_IFELSE1 :
521 : {
522 0 : if ( nParameters == 3 )
523 0 : aEquation = "if(" + sParameters[ 0 ] + ","
524 0 : + sParameters[ 1 ] + "," + sParameters[ 2 ] + ")";
525 : }
526 0 : break;
527 : case FC_ABS :
528 : {
529 0 : if ( nParameters == 1 )
530 0 : aEquation = "abs(" + sParameters[ 0 ] + ")";
531 : }
532 0 : break;
533 : case FC_AT2 :
534 : {
535 0 : if ( nParameters == 2 )
536 0 : aEquation = "(10800000*atan2(" + sParameters[ 1 ] + ","
537 0 : + sParameters[ 0 ] + "))/pi";
538 : }
539 0 : break;
540 : case FC_CAT2 :
541 : {
542 0 : if ( nParameters == 3 )
543 0 : aEquation = sParameters[ 0 ] + "*(cos(atan2(" +
544 0 : sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
545 : }
546 0 : break;
547 : case FC_COS :
548 : {
549 0 : if ( nParameters == 2 )
550 0 : aEquation = sParameters[ 0 ] + "*cos(pi*(" +
551 0 : sParameters[ 1 ] + ")/10800000)";
552 : }
553 0 : break;
554 : case FC_MAX :
555 : {
556 0 : if ( nParameters == 2 )
557 0 : aEquation = "max(" + sParameters[ 0 ] + "," +
558 0 : sParameters[ 1 ] + ")";
559 : }
560 0 : break;
561 : case FC_MIN :
562 : {
563 0 : if ( nParameters == 2 )
564 0 : aEquation = "min(" + sParameters[ 0 ] + "," +
565 0 : sParameters[ 1 ] + ")";
566 : }
567 0 : break;
568 : case FC_MOD :
569 : {
570 0 : if ( nParameters == 3 )
571 0 : aEquation = "sqrt("
572 0 : + sParameters[ 0 ] + "*" + sParameters[ 0 ] + "+"
573 0 : + sParameters[ 1 ] + "*" + sParameters[ 1 ] + "+"
574 0 : + sParameters[ 2 ] + "*" + sParameters[ 2 ] + ")";
575 : }
576 0 : break;
577 : case FC_PIN :
578 : {
579 0 : if ( nParameters == 3 ) // if(x-y,x,if(y-z,z,y))
580 0 : aEquation = "if(" + sParameters[ 0 ] + "-" + sParameters[ 1 ]
581 0 : + "," + sParameters[ 0 ] + ",if(" + sParameters[ 2 ]
582 0 : + "-" + sParameters[ 1 ] + "," + sParameters[ 1 ]
583 0 : + "," + sParameters[ 2 ] + "))";
584 : }
585 0 : break;
586 : case FC_SAT2 :
587 : {
588 0 : if ( nParameters == 3 )
589 0 : aEquation = sParameters[ 0 ] + "*(sin(atan2(" +
590 0 : sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
591 : }
592 0 : break;
593 : case FC_SIN :
594 : {
595 0 : if ( nParameters == 2 )
596 0 : aEquation = sParameters[ 0 ] + "*sin(pi*(" +
597 0 : sParameters[ 1 ] + ")/10800000)";
598 : }
599 0 : break;
600 : case FC_SQRT :
601 : {
602 0 : if ( nParameters == 1 )
603 0 : aEquation = "sqrt(" + sParameters[ 0 ] + ")";
604 : }
605 0 : break;
606 : case FC_TAN :
607 : {
608 0 : if ( nParameters == 2 )
609 0 : aEquation = sParameters[ 0 ] + "*tan(pi*(" +
610 0 : sParameters[ 1 ] + ")/10800000)";
611 : }
612 0 : break;
613 : case FC_VAL :
614 : {
615 13 : if ( nParameters == 1 )
616 13 : aEquation = sParameters[ 0 ];
617 : }
618 13 : break;
619 : default :
620 0 : break;
621 : }
622 668 : }
623 : }
624 167 : return aEquation;
625 : }
626 :
627 167 : ContextHandlerRef GeomGuideListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
628 : {
629 167 : if ( aElementToken == A_TOKEN( gd ) ) // CT_GeomGuide
630 : {
631 167 : CustomShapeGuide aGuide;
632 167 : aGuide.maName = rAttribs.getString( XML_name ).get();
633 167 : aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, rAttribs.getString( XML_fmla ).get() );
634 167 : mrGuideList.push_back( aGuide );
635 : }
636 167 : return this;
637 : }
638 :
639 : // ---------------------------------------------------------------------
640 :
641 0 : static const OUString GetGeomGuideName( const OUString& rValue )
642 : {
643 0 : return rValue;
644 : }
645 :
646 : // ---------------------------------------------------------------------
647 : // CT_AdjPoint2D
648 84 : class AdjPoint2DContext : public ContextHandler2
649 : {
650 : public:
651 : AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
652 : };
653 :
654 42 : AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
655 42 : : ContextHandler2( rParent )
656 : {
657 42 : rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_x ).get(), sal_True );
658 42 : rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_y ).get(), sal_True );
659 42 : }
660 :
661 : // ---------------------------------------------------------------------
662 : // CT_XYAdjustHandle
663 0 : class XYAdjustHandleContext : public ContextHandler2
664 : {
665 : public:
666 : XYAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
667 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
668 :
669 : protected:
670 : AdjustHandle& mrAdjustHandle;
671 : CustomShapeProperties& mrCustomShapeProperties;
672 : };
673 :
674 0 : XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
675 : : ContextHandler2( rParent )
676 : , mrAdjustHandle( rAdjustHandle )
677 0 : , mrCustomShapeProperties( rCustomShapeProperties )
678 : {
679 0 : const OUString aEmptyDefault;
680 0 : if ( rAttribs.hasAttribute( XML_gdRefX ) )
681 : {
682 0 : mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefX, aEmptyDefault ) );
683 : }
684 0 : if ( rAttribs.hasAttribute( XML_minX ) )
685 : {
686 0 : mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minX, aEmptyDefault ), sal_True );
687 : }
688 0 : if ( rAttribs.hasAttribute( XML_maxX ) )
689 : {
690 0 : mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxX, aEmptyDefault ), sal_True );
691 : }
692 0 : if ( rAttribs.hasAttribute( XML_gdRefY ) )
693 : {
694 0 : mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefY, aEmptyDefault ) );
695 : }
696 0 : if ( rAttribs.hasAttribute( XML_minY ) )
697 : {
698 0 : mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minY, aEmptyDefault ), sal_True );
699 : }
700 0 : if ( rAttribs.hasAttribute( XML_maxY ) )
701 : {
702 0 : mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxY, aEmptyDefault ), sal_True );
703 0 : }
704 0 : }
705 :
706 0 : ContextHandlerRef XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
707 : {
708 0 : if ( aElementToken == A_TOKEN( pos ) )
709 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
710 0 : return 0;
711 : }
712 :
713 : // ---------------------------------------------------------------------
714 : // CT_PolarAdjustHandle
715 0 : class PolarAdjustHandleContext : public ContextHandler2
716 : {
717 : public:
718 : PolarAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle );
719 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
720 :
721 : protected:
722 : AdjustHandle& mrAdjustHandle;
723 : CustomShapeProperties& mrCustomShapeProperties;
724 : };
725 :
726 0 : PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
727 : : ContextHandler2( rParent )
728 : , mrAdjustHandle( rAdjustHandle )
729 0 : , mrCustomShapeProperties( rCustomShapeProperties )
730 : {
731 0 : const OUString aEmptyDefault;
732 0 : if ( rAttribs.hasAttribute( XML_gdRefR ) )
733 : {
734 0 : mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefR, aEmptyDefault ) );
735 : }
736 0 : if ( rAttribs.hasAttribute( XML_minR ) )
737 : {
738 0 : mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minR, aEmptyDefault ), sal_True );
739 : }
740 0 : if ( rAttribs.hasAttribute( XML_maxR ) )
741 : {
742 0 : mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxR, aEmptyDefault ), sal_True );
743 : }
744 0 : if ( rAttribs.hasAttribute( XML_gdRefAng ) )
745 : {
746 0 : mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefAng, aEmptyDefault ) );
747 : }
748 0 : if ( rAttribs.hasAttribute( XML_minAng ) )
749 : {
750 0 : mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minAng, aEmptyDefault ) );
751 : }
752 0 : if ( rAttribs.hasAttribute( XML_maxAng ) )
753 : {
754 0 : mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxAng, aEmptyDefault ) );
755 0 : }
756 0 : }
757 :
758 0 : ContextHandlerRef PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
759 : {
760 0 : if ( aElementToken == A_TOKEN( pos ) )
761 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
762 0 : return 0;
763 : }
764 :
765 : // ---------------------------------------------------------------------
766 : // CT_AdjustHandleList
767 14 : class AdjustHandleListContext : public ContextHandler2
768 : {
769 : public:
770 : AdjustHandleListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList );
771 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
772 :
773 : protected:
774 : std::vector< AdjustHandle >& mrAdjustHandleList;
775 : CustomShapeProperties& mrCustomShapeProperties;
776 : };
777 :
778 7 : AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
779 : : ContextHandler2( rParent )
780 : , mrAdjustHandleList( rAdjustHandleList )
781 7 : , mrCustomShapeProperties( rCustomShapeProperties )
782 : {
783 7 : }
784 :
785 0 : ContextHandlerRef AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
786 : {
787 0 : if ( aElementToken == A_TOKEN( ahXY ) ) // CT_XYAdjustHandle
788 : {
789 0 : AdjustHandle aAdjustHandle( sal_False );
790 0 : mrAdjustHandleList.push_back( aAdjustHandle );
791 0 : return new XYAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
792 : }
793 0 : else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
794 : {
795 0 : AdjustHandle aAdjustHandle( sal_True );
796 0 : mrAdjustHandleList.push_back( aAdjustHandle );
797 0 : return new PolarAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
798 : }
799 0 : return 0;
800 : }
801 :
802 : // ---------------------------------------------------------------------
803 : // CT_ConnectionSite
804 26 : class ConnectionSiteContext : public ContextHandler2
805 : {
806 : public:
807 : ConnectionSiteContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite );
808 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
809 :
810 : protected:
811 : ConnectionSite& mrConnectionSite;
812 : CustomShapeProperties& mrCustomShapeProperties;
813 : };
814 :
815 13 : ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
816 : : ContextHandler2( rParent )
817 : , mrConnectionSite( rConnectionSite )
818 13 : , mrCustomShapeProperties( rCustomShapeProperties )
819 : {
820 13 : mrConnectionSite.ang = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_ang ).get() );
821 13 : }
822 :
823 13 : ContextHandlerRef ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
824 : {
825 13 : if ( aElementToken == A_TOKEN( pos ) )
826 13 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
827 0 : return 0;
828 : }
829 :
830 : // ---------------------------------------------------------------------
831 : // CT_Path2DMoveTo
832 6 : class Path2DMoveToContext : public ContextHandler2
833 : {
834 : public:
835 : Path2DMoveToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
836 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
837 :
838 : protected:
839 : EnhancedCustomShapeParameterPair& mrAdjPoint2D;
840 : CustomShapeProperties& mrCustomShapeProperties;
841 : };
842 :
843 3 : Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
844 : : ContextHandler2( rParent )
845 : , mrAdjPoint2D( rAdjPoint2D )
846 3 : , mrCustomShapeProperties( rCustomShapeProperties )
847 : {
848 3 : }
849 :
850 3 : ContextHandlerRef Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
851 : {
852 3 : if ( aElementToken == A_TOKEN( pt ) )
853 3 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
854 0 : return 0;
855 : }
856 :
857 : // ---------------------------------------------------------------------
858 : // CT_Path2DLineTo
859 4 : class Path2DLineToContext : public ContextHandler2
860 : {
861 : public:
862 : Path2DLineToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
863 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
864 :
865 : protected:
866 : EnhancedCustomShapeParameterPair& mrAdjPoint2D;
867 : CustomShapeProperties& mrCustomShapeProperties;
868 : };
869 :
870 2 : Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
871 : : ContextHandler2( rParent )
872 : , mrAdjPoint2D( rAdjPoint2D )
873 2 : , mrCustomShapeProperties( rCustomShapeProperties )
874 : {
875 2 : }
876 :
877 2 : ContextHandlerRef Path2DLineToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
878 : {
879 2 : if ( aElementToken == A_TOKEN( pt ) )
880 2 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
881 0 : return 0;
882 : }
883 :
884 : // ---------------------------------------------------------------------
885 : // CT_Path2DQuadBezierTo
886 0 : class Path2DQuadBezierToContext : public ContextHandler2
887 : {
888 : public:
889 : Path2DQuadBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rPt1, EnhancedCustomShapeParameterPair& rPt2 );
890 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
891 :
892 : protected:
893 : EnhancedCustomShapeParameterPair& mrPt1;
894 : EnhancedCustomShapeParameterPair& mrPt2;
895 : int nCount;
896 : CustomShapeProperties& mrCustomShapeProperties;
897 : };
898 :
899 0 : Path2DQuadBezierToContext::Path2DQuadBezierToContext( ContextHandler2Helper& rParent,
900 : CustomShapeProperties& rCustomShapeProperties,
901 : EnhancedCustomShapeParameterPair& rPt1,
902 : EnhancedCustomShapeParameterPair& rPt2 )
903 : : ContextHandler2( rParent )
904 : , mrPt1( rPt1 )
905 : , mrPt2( rPt2 )
906 : , nCount( 0 )
907 0 : , mrCustomShapeProperties( rCustomShapeProperties )
908 : {
909 0 : }
910 :
911 0 : ContextHandlerRef Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
912 : {
913 0 : if ( aElementToken == A_TOKEN( pt ) )
914 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
915 0 : return 0;
916 : }
917 :
918 : // ---------------------------------------------------------------------
919 : // CT_Path2DCubicBezierTo
920 16 : class Path2DCubicBezierToContext : public ContextHandler2
921 : {
922 : public:
923 : Path2DCubicBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties,
924 : EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair&, EnhancedCustomShapeParameterPair& );
925 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
926 :
927 : protected:
928 : CustomShapeProperties& mrCustomShapeProperties;
929 : EnhancedCustomShapeParameterPair& mrControlPt1;
930 : EnhancedCustomShapeParameterPair& mrControlPt2;
931 : EnhancedCustomShapeParameterPair& mrEndPt;
932 : int nCount;
933 : };
934 :
935 8 : Path2DCubicBezierToContext::Path2DCubicBezierToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties,
936 : EnhancedCustomShapeParameterPair& rControlPt1,
937 : EnhancedCustomShapeParameterPair& rControlPt2,
938 : EnhancedCustomShapeParameterPair& rEndPt )
939 : : ContextHandler2( rParent )
940 : , mrCustomShapeProperties( rCustomShapeProperties )
941 : , mrControlPt1( rControlPt1 )
942 : , mrControlPt2( rControlPt2 )
943 : , mrEndPt( rEndPt )
944 8 : , nCount( 0 )
945 : {
946 8 : }
947 :
948 24 : ContextHandlerRef Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
949 : {
950 24 : if ( aElementToken == A_TOKEN( pt ) )
951 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties,
952 24 : nCount++ ? nCount == 2 ? mrControlPt2 : mrEndPt : mrControlPt1 ); // CT_AdjPoint2D
953 0 : return 0;
954 : }
955 :
956 : // ---------------------------------------------------------------------
957 : // CT_Path2DContext
958 : class Path2DContext : public ContextHandler2
959 : {
960 : public:
961 : Path2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D );
962 : virtual ~Path2DContext();
963 : virtual ::oox::core::ContextHandlerRef
964 : onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
965 :
966 : protected:
967 : Path2D& mrPath2D;
968 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& mrSegments;
969 : CustomShapeProperties& mrCustomShapeProperties;
970 : };
971 :
972 3 : Path2DContext::Path2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments, Path2D& rPath2D )
973 : : ContextHandler2( rParent )
974 : , mrPath2D( rPath2D )
975 : , mrSegments( rSegments )
976 3 : , mrCustomShapeProperties( rCustomShapeProperties )
977 : {
978 3 : const OUString aEmptyString;
979 :
980 3 : rPath2D.w = rAttribs.getString( XML_w, aEmptyString ).toInt64();
981 3 : rPath2D.h = rAttribs.getString( XML_h, aEmptyString ).toInt64();
982 3 : rPath2D.fill = rAttribs.getToken( XML_fill, XML_norm );
983 3 : rPath2D.stroke = rAttribs.getBool( XML_stroke, sal_True );
984 3 : rPath2D.extrusionOk = rAttribs.getBool( XML_extrusionOk, sal_True );
985 3 : }
986 :
987 9 : Path2DContext::~Path2DContext()
988 : {
989 3 : EnhancedCustomShapeSegment aNewSegment;
990 3 : switch ( mrPath2D.fill )
991 : {
992 : case XML_none:
993 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
994 0 : break;
995 : case XML_darken:
996 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKEN;
997 0 : break;
998 : case XML_darkenLess:
999 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKENLESS;
1000 0 : break;
1001 : case XML_lighten:
1002 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTEN;
1003 0 : break;
1004 : case XML_lightenLess:
1005 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
1006 0 : break;
1007 : }
1008 3 : if (mrPath2D.fill != XML_norm) {
1009 0 : aNewSegment.Count = 0;
1010 0 : mrSegments.push_back( aNewSegment );
1011 : }
1012 3 : if ( !mrPath2D.stroke )
1013 : {
1014 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
1015 0 : aNewSegment.Count = 0;
1016 0 : mrSegments.push_back( aNewSegment );
1017 : }
1018 3 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
1019 3 : aNewSegment.Count = 0;
1020 3 : mrSegments.push_back( aNewSegment );
1021 6 : }
1022 :
1023 14 : ContextHandlerRef Path2DContext::onCreateContext( sal_Int32 aElementToken,
1024 : const AttributeList& rAttribs )
1025 : {
1026 14 : switch( aElementToken )
1027 : {
1028 : case A_TOKEN( close ) :
1029 : {
1030 : // ignore close after move to (ppt does seems to do the same, see accentCallout2 preset for example)
1031 1 : if ( mrSegments.empty() || ( mrSegments.back().Command != EnhancedCustomShapeSegmentCommand::MOVETO ) ) {
1032 1 : EnhancedCustomShapeSegment aNewSegment;
1033 1 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
1034 1 : aNewSegment.Count = 0;
1035 1 : mrSegments.push_back( aNewSegment );
1036 : }
1037 : }
1038 1 : break;
1039 : case A_TOKEN( moveTo ) :
1040 : {
1041 3 : EnhancedCustomShapeSegment aNewSegment;
1042 3 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
1043 3 : aNewSegment.Count = 1;
1044 3 : mrSegments.push_back( aNewSegment );
1045 :
1046 3 : EnhancedCustomShapeParameterPair aAdjPoint2D;
1047 3 : mrPath2D.parameter.push_back( aAdjPoint2D );
1048 3 : return new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1049 : }
1050 : break;
1051 : case A_TOKEN( lnTo ) :
1052 : {
1053 2 : if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
1054 0 : mrSegments.back().Count++;
1055 : else
1056 : {
1057 2 : EnhancedCustomShapeSegment aSegment;
1058 2 : aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
1059 2 : aSegment.Count = 1;
1060 2 : mrSegments.push_back( aSegment );
1061 : }
1062 2 : EnhancedCustomShapeParameterPair aAdjPoint2D;
1063 2 : mrPath2D.parameter.push_back( aAdjPoint2D );
1064 2 : return new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1065 : }
1066 : break;
1067 : case A_TOKEN( arcTo ) : // CT_Path2DArcTo
1068 : {
1069 0 : if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCANGLETO ) )
1070 0 : mrSegments.back().Count++;
1071 : else
1072 : {
1073 0 : EnhancedCustomShapeSegment aSegment;
1074 0 : aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCANGLETO;
1075 0 : aSegment.Count = 1;
1076 0 : mrSegments.push_back( aSegment );
1077 : }
1078 :
1079 0 : EnhancedCustomShapeParameterPair aScale;
1080 0 : EnhancedCustomShapeParameterPair aAngles;
1081 :
1082 0 : aScale.First = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_wR ).get(), sal_True );
1083 0 : aScale.Second = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_hR ).get(), sal_True );
1084 :
1085 0 : CustomShapeGuide aGuide;
1086 0 : sal_Int32 nArcNum = mrCustomShapeProperties.getArcNum();
1087 :
1088 : // start angle
1089 0 : aGuide.maName = "arctosa" + OUString::valueOf( nArcNum );
1090 0 : aGuide.maFormula = "("
1091 0 : + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_stAng ).get() ) )
1092 0 : + ")/60000.0";
1093 0 : aAngles.First.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide ) );
1094 0 : aAngles.First.Type = EnhancedCustomShapeParameterType::EQUATION;
1095 :
1096 : // swing angle
1097 0 : aGuide.maName = "arctosw" + OUString::valueOf( nArcNum );
1098 0 : aGuide.maFormula = "("
1099 0 : + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_swAng ).get() ) )
1100 0 : + ")/60000.0";
1101 0 : aAngles.Second.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide ) );
1102 0 : aAngles.Second.Type = EnhancedCustomShapeParameterType::EQUATION;
1103 :
1104 0 : mrPath2D.parameter.push_back( aScale );
1105 0 : mrPath2D.parameter.push_back( aAngles );
1106 : }
1107 0 : break;
1108 : case A_TOKEN( quadBezTo ) :
1109 : {
1110 0 : if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
1111 0 : mrSegments.back().Count++;
1112 : else
1113 : {
1114 0 : EnhancedCustomShapeSegment aSegment;
1115 0 : aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
1116 0 : aSegment.Count = 1;
1117 0 : mrSegments.push_back( aSegment );
1118 : }
1119 0 : EnhancedCustomShapeParameterPair aPt1;
1120 0 : EnhancedCustomShapeParameterPair aPt2;
1121 0 : mrPath2D.parameter.push_back( aPt1 );
1122 0 : mrPath2D.parameter.push_back( aPt2 );
1123 : return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties,
1124 0 : mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1125 0 : mrPath2D.parameter.back() );
1126 : }
1127 : break;
1128 : case A_TOKEN( cubicBezTo ) :
1129 : {
1130 8 : if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
1131 4 : mrSegments.back().Count++;
1132 : else
1133 : {
1134 4 : EnhancedCustomShapeSegment aSegment;
1135 4 : aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
1136 4 : aSegment.Count = 1;
1137 4 : mrSegments.push_back( aSegment );
1138 : }
1139 8 : EnhancedCustomShapeParameterPair aControlPt1;
1140 16 : EnhancedCustomShapeParameterPair aControlPt2;
1141 16 : EnhancedCustomShapeParameterPair aEndPt;
1142 8 : mrPath2D.parameter.push_back( aControlPt1 );
1143 8 : mrPath2D.parameter.push_back( aControlPt2 );
1144 8 : mrPath2D.parameter.push_back( aEndPt );
1145 : return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties,
1146 8 : mrPath2D.parameter[ mrPath2D.parameter.size() - 3 ],
1147 8 : mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1148 24 : mrPath2D.parameter.back() );
1149 : }
1150 : break;
1151 : }
1152 1 : return 0;
1153 : }
1154 :
1155 : // ---------------------------------------------------------------------
1156 : // CT_Path2DList
1157 14 : class Path2DListContext : public ContextHandler2
1158 : {
1159 : public:
1160 : Path2DListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1161 : std::vector< Path2D >& rPath2DList );
1162 :
1163 : virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
1164 :
1165 : protected:
1166 :
1167 : CustomShapeProperties& mrCustomShapeProperties;
1168 : std::vector< com::sun::star::drawing::EnhancedCustomShapeSegment >& mrSegments;
1169 : std::vector< Path2D >& mrPath2DList;
1170 : };
1171 :
1172 7 : Path2DListContext::Path2DListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< EnhancedCustomShapeSegment >& rSegments,
1173 : std::vector< Path2D >& rPath2DList )
1174 : : ContextHandler2( rParent )
1175 : , mrCustomShapeProperties( rCustomShapeProperties )
1176 : , mrSegments( rSegments )
1177 7 : , mrPath2DList( rPath2DList )
1178 : {
1179 7 : }
1180 :
1181 3 : ContextHandlerRef Path2DListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1182 : {
1183 3 : if ( aElementToken == A_TOKEN( path ) )
1184 : {
1185 3 : Path2D aPath2D;
1186 3 : mrPath2DList.push_back( aPath2D );
1187 3 : return new Path2DContext( *this, rAttribs, mrCustomShapeProperties, mrSegments, mrPath2DList.back() );
1188 : }
1189 0 : return 0;
1190 : }
1191 :
1192 : // ---------------------------------------------------------------------
1193 : // CT_CustomGeometry2D
1194 7 : CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& /* rAttribs */, CustomShapeProperties& rCustomShapeProperties )
1195 : : ContextHandler2( rParent )
1196 7 : , mrCustomShapeProperties( rCustomShapeProperties )
1197 : {
1198 7 : }
1199 :
1200 55 : ContextHandlerRef CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1201 : {
1202 55 : switch( aElementToken )
1203 : {
1204 : case A_TOKEN( avLst ): // CT_GeomGuideList adjust value list
1205 7 : return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1206 : case A_TOKEN( gdLst ): // CT_GeomGuideList guide list
1207 7 : return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getGuideList() );
1208 : case A_TOKEN( ahLst ): // CT_AdjustHandleList adjust handle list
1209 7 : return new AdjustHandleListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustHandleList() );
1210 : case A_TOKEN( cxnLst ): // CT_ConnectionSiteList connection site list
1211 7 : return this;
1212 : case A_TOKEN( rect ): // CT_GeomRectList geometry rect list
1213 : {
1214 7 : GeomRect aGeomRect;
1215 7 : aGeomRect.l = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_l ).get(), sal_True );
1216 7 : aGeomRect.t = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_t ).get(), sal_True );
1217 7 : aGeomRect.r = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_r ).get(), sal_True );
1218 7 : aGeomRect.b = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_b ).get(), sal_True );
1219 7 : mrCustomShapeProperties.getTextRect() = aGeomRect;
1220 : }
1221 7 : break;
1222 : case A_TOKEN( pathLst ): // CT_Path2DList 2d path list
1223 7 : return new Path2DListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getSegments(), mrCustomShapeProperties.getPath2DList() );
1224 :
1225 : // from cxnLst:
1226 : case A_TOKEN( cxn ): // CT_ConnectionSite
1227 : {
1228 13 : ConnectionSite aConnectionSite;
1229 13 : mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
1230 13 : return new ConnectionSiteContext( *this, rAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
1231 : }
1232 : }
1233 7 : return 0;
1234 : }
1235 :
1236 : // ---------------------------------------------------------------------
1237 : // CT_PresetGeometry2D
1238 131 : PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1239 : : ContextHandler2( rParent )
1240 131 : , mrCustomShapeProperties( rCustomShapeProperties )
1241 : {
1242 131 : sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1243 : OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1244 131 : mrCustomShapeProperties.setShapePresetType( nShapeType );
1245 131 : }
1246 :
1247 131 : ContextHandlerRef PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1248 : {
1249 131 : if ( aElementToken == A_TOKEN( avLst ) )
1250 131 : return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1251 : else
1252 0 : return this;
1253 : }
1254 :
1255 : // ---------------------------------------------------------------------
1256 : // CT_PresetTextShape
1257 0 : PresetTextShapeContext::PresetTextShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1258 : : ContextHandler2( rParent )
1259 0 : , mrCustomShapeProperties( rCustomShapeProperties )
1260 : {
1261 0 : sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1262 : OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1263 0 : mrCustomShapeProperties.setShapePresetType( nShapeType );
1264 0 : }
1265 :
1266 0 : ContextHandlerRef PresetTextShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1267 : {
1268 0 : if ( aElementToken == A_TOKEN( avLst ) )
1269 0 : return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1270 : else
1271 0 : return this;
1272 : }
1273 :
1274 141 : } }
1275 :
1276 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|