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