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 0 : OUString GetFormulaParameter( const EnhancedCustomShapeParameter& rParameter )
91 : {
92 0 : OUString aRet;
93 0 : switch( rParameter.Type )
94 : {
95 : case EnhancedCustomShapeParameterType::NORMAL :
96 : {
97 0 : 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 0 : sal_Int32 nValue = 0;
106 0 : if ( rParameter.Value >>= nValue )
107 0 : aRet = OUString::number( nValue );
108 : }
109 : }
110 0 : break;
111 : case EnhancedCustomShapeParameterType::EQUATION :
112 : {
113 0 : if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
114 : {
115 : sal_Int32 nFormulaIndex;
116 0 : if ( rParameter.Value >>= nFormulaIndex )
117 : {
118 0 : aRet = "?"
119 0 : + OUString::number( nFormulaIndex )
120 0 : + " ";
121 : }
122 : }
123 : else
124 : {
125 : // ups... we should have an index here and not the formula name
126 : }
127 : }
128 0 : break;
129 : case EnhancedCustomShapeParameterType::ADJUSTMENT :
130 : {
131 0 : if ( rParameter.Value.getValueTypeClass() == TypeClass_LONG )
132 : {
133 : sal_Int32 nAdjustmentIndex;
134 0 : if ( rParameter.Value >>= nAdjustmentIndex )
135 : {
136 0 : aRet = "$"
137 0 : + OUString::number( nAdjustmentIndex )
138 0 : + " ";
139 : }
140 : }
141 : else
142 : {
143 : // ups... we should have an index here and not the formula name
144 : }
145 : }
146 0 : 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 0 : const OUString sLogWidth( "logwidth" );
210 0 : aRet = sLogWidth;
211 : }
212 0 : break;
213 : case EnhancedCustomShapeParameterType::LOGHEIGHT :
214 : {
215 0 : const OUString sLogHeight( "logheight" );
216 0 : aRet = sLogHeight;
217 : }
218 0 : break;
219 : }
220 0 : return aRet;
221 : }
222 :
223 :
224 :
225 0 : static EnhancedCustomShapeParameter GetAdjCoordinate( CustomShapeProperties& rCustomShapeProperties, const OUString& rValue, bool bNoSymbols = true )
226 : {
227 0 : com::sun::star::drawing::EnhancedCustomShapeParameter aRet;
228 0 : if ( !rValue.isEmpty() )
229 : {
230 0 : bool bConstant = true;
231 0 : sal_Int32 nConstant = -1;
232 0 : sal_Int32 nIntVal = 0;
233 :
234 : // first check if it's a constant value
235 0 : switch( AttributeConversion::decodeToken( rValue ) )
236 : {
237 0 : 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 0 : case XML_cd2 : nConstant = 180 * 60000; break;
242 0 : case XML_cd3 : nConstant = 120 * 60000; break;
243 0 : 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 0 : if ( bNoSymbols )
250 : {
251 0 : CustomShapeGuide aGuide;
252 0 : aGuide.maName = rValue;
253 0 : aGuide.maFormula = "logheight" ;
254 :
255 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
256 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
257 : }
258 : else
259 0 : aRet.Type = EnhancedCustomShapeParameterType::LOGHEIGHT; // TODO: HEIGHT needs to be implemented
260 : }
261 0 : break;
262 :
263 :
264 : case XML_hd10 : // !!PASSTHROUGH INTENDED
265 0 : nIntVal += 2; // */ h 1.0 10.0
266 : case XML_hd8 : // */ h 1.0 8.0
267 0 : nIntVal += 2;
268 : case XML_hd6 : // */ h 1.0 6.0
269 0 : nIntVal++;
270 : case XML_hd5 : // */ h 1.0 5.0
271 0 : nIntVal++;
272 : case XML_hd4 : // */ h 1.0 4.0
273 0 : nIntVal++;
274 : case XML_hd3 : // */ h 1.0 3.0
275 0 : nIntVal++;
276 : case XML_hd2 : // */ h 1.0 2.0
277 : case XML_vc : // */ h 1.0 2.0
278 : {
279 0 : nIntVal += 2;
280 :
281 0 : CustomShapeGuide aGuide;
282 0 : aGuide.maName = rValue;
283 0 : aGuide.maFormula = "logheight/" + OUString::number( nIntVal );
284 :
285 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
286 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
287 : }
288 0 : break;
289 :
290 : case XML_t :
291 : case XML_l :
292 : {
293 0 : nConstant = 0;
294 0 : aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
295 : }
296 0 : 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 0 : CustomShapeGuide aGuide;
311 0 : aGuide.maName = rValue;
312 0 : aGuide.maFormula = "min(logwidth,logheight)";
313 :
314 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
315 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
316 : }
317 0 : break;
318 : case XML_ssd32 : // */ ss 1.0 32.0
319 0 : nIntVal += 16;
320 : case XML_ssd16 : // */ ss 1.0 16.0
321 0 : nIntVal += 8;
322 : case XML_ssd8 : // */ ss 1.0 8.0
323 0 : nIntVal += 2;
324 : case XML_ssd6 : // */ ss 1.0 6.0
325 0 : nIntVal += 2;
326 : case XML_ssd4 : // */ ss 1.0 4.0
327 0 : nIntVal += 2;
328 : case XML_ssd2 : // */ ss 1.0 2.0
329 : {
330 0 : nIntVal += 2;
331 :
332 0 : CustomShapeGuide aGuide;
333 0 : aGuide.maName = rValue;
334 0 : aGuide.maFormula = "min(logwidth,logheight)/" + OUString::number( nIntVal );
335 :
336 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
337 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
338 : }
339 0 : break;
340 :
341 : case XML_r : // variable width of the shape defined in spPr
342 : case XML_w :
343 : {
344 0 : if ( bNoSymbols )
345 : {
346 0 : CustomShapeGuide aGuide;
347 0 : aGuide.maName = rValue;
348 0 : aGuide.maFormula = "logwidth" ;
349 :
350 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
351 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
352 : }
353 : else
354 0 : aRet.Type = EnhancedCustomShapeParameterType::LOGWIDTH;
355 : }
356 0 : break;
357 :
358 : case XML_wd32 : // */ w 1.0 32.0
359 0 : nIntVal += 20;
360 : case XML_wd12 : // */ w 1.0 12.0
361 0 : nIntVal += 2;
362 : case XML_wd10 : // */ w 1.0 10.0
363 0 : nIntVal += 2;
364 : case XML_wd8 : // */ w 1.0 8.0
365 0 : nIntVal += 2;
366 : case XML_wd6 : // */ w 1.0 6.0
367 0 : nIntVal++;
368 : case XML_wd5 : // */ w 1.0 5.0
369 0 : nIntVal++;
370 : case XML_wd4 : // */ w 1.0 4.0
371 0 : nIntVal++;
372 : case XML_wd3 : // */ w 1.0 3.0
373 0 : nIntVal++;
374 : case XML_hc : // */ w 1.0 2.0
375 : case XML_wd2 : // */ w 1.0 2.0
376 : {
377 0 : nIntVal += 2;
378 :
379 0 : CustomShapeGuide aGuide;
380 0 : aGuide.maName = rValue;
381 0 : aGuide.maFormula = "logwidth/" + OUString::number( nIntVal );
382 :
383 0 : aRet.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), aGuide ) );
384 0 : aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
385 : }
386 0 : break;
387 :
388 : default:
389 0 : bConstant = false;
390 0 : break;
391 : }
392 0 : if ( bConstant )
393 : {
394 0 : if (nConstant != -1) {
395 0 : aRet.Value = Any( nConstant );
396 0 : aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
397 : }
398 : }
399 : else
400 : {
401 0 : sal_Unicode n = rValue[ 0 ];
402 0 : if ( ( n == '+' ) || ( n == '-' ) )
403 : {
404 0 : if ( rValue.getLength() > 1 )
405 0 : n = rValue[ 1 ];
406 : }
407 0 : if ( ( n >= '0' ) && ( n <= '9' ) )
408 : { // seems to be a ST_Coordinate
409 0 : aRet.Value = Any( (sal_Int32)(rValue.toInt32() ) );
410 0 : aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
411 : }
412 : else
413 : {
414 0 : sal_Int32 nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getAdjustmentGuideList(), rValue );
415 0 : if ( nGuideIndex >= 0 )
416 : {
417 0 : aRet.Value = Any( nGuideIndex );
418 0 : aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
419 : }
420 : else
421 : {
422 0 : nGuideIndex = CustomShapeProperties::GetCustomShapeGuideValue( rCustomShapeProperties.getGuideList(), rValue );
423 0 : if ( nGuideIndex >= 0 )
424 : {
425 0 : aRet.Value = Any( nGuideIndex );
426 0 : 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 0 : return aRet;
438 : }
439 :
440 :
441 : // CT_GeomGuideList
442 0 : 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 0 : GeomGuideListContext::GeomGuideListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< CustomShapeGuide >& rGuideList )
454 : : ContextHandler2( rParent )
455 : , mrGuideList( rGuideList )
456 0 : , mrCustomShapeProperties( rCustomShapeProperties )
457 : {
458 0 : }
459 :
460 0 : static OUString convertToOOEquation( CustomShapeProperties& rCustomShapeProperties, const OUString& rSource )
461 : {
462 0 : if ( !pCommandHashMap )
463 : {
464 0 : FormulaCommandHMap* pHM = new FormulaCommandHMap();
465 0 : for( sal_Int32 i = 0; i < FC_LAST; i++ )
466 0 : (*pHM)[ OUString::createFromAscii( pFormularCommandNameTable[ i ].pS ) ] = pFormularCommandNameTable[ i ].pE;
467 0 : pCommandHashMap = pHM;
468 : }
469 :
470 0 : std::vector< OUString > aTokens;
471 0 : sal_Int32 nIndex = 0;
472 0 : do
473 : {
474 0 : OUString aToken( rSource.getToken( 0, ' ', nIndex ) );
475 0 : if ( !aToken.isEmpty() )
476 0 : aTokens.push_back( aToken );
477 : }
478 0 : while ( nIndex >= 0 );
479 :
480 0 : OUString aEquation;
481 0 : if ( !aTokens.empty() )
482 : {
483 0 : sal_Int32 i, nParameters = aTokens.size() - 1;
484 0 : if ( nParameters > 3 )
485 0 : nParameters = 3;
486 :
487 0 : OUString sParameters[ 3 ];
488 :
489 0 : for ( i = 0; i < nParameters; i++ )
490 0 : sParameters[ i ] = GetFormulaParameter( GetAdjCoordinate( rCustomShapeProperties, aTokens[ i + 1 ], false ) );
491 :
492 0 : const FormulaCommandHMap::const_iterator aIter( pCommandHashMap->find( aTokens[ 0 ] ) );
493 0 : if ( aIter != pCommandHashMap->end() )
494 : {
495 0 : switch( aIter->second )
496 : {
497 : case FC_MULDIV :
498 : {
499 0 : if ( nParameters == 3 )
500 0 : aEquation = sParameters[ 0 ] + "*" + sParameters[ 1 ]
501 0 : + "/" + sParameters[ 2 ];
502 : }
503 0 : break;
504 : case FC_PLUSMINUS :
505 : {
506 0 : if ( nParameters == 3 )
507 0 : aEquation = sParameters[ 0 ] + "+" + sParameters[ 1 ]
508 0 : + "-" + sParameters[ 2 ];
509 : }
510 0 : break;
511 : case FC_PLUSDIV :
512 : {
513 0 : if ( nParameters == 3 )
514 0 : aEquation = "(" + sParameters[ 0 ] + "+"
515 0 : + sParameters[ 1 ] + ")/" + sParameters[ 2 ];
516 : }
517 0 : break;
518 : case FC_IFELSE :
519 : case FC_IFELSE1 :
520 : {
521 0 : if ( nParameters == 3 )
522 0 : aEquation = "if(" + sParameters[ 0 ] + ","
523 0 : + sParameters[ 1 ] + "," + sParameters[ 2 ] + ")";
524 : }
525 0 : break;
526 : case FC_ABS :
527 : {
528 0 : if ( nParameters == 1 )
529 0 : aEquation = "abs(" + sParameters[ 0 ] + ")";
530 : }
531 0 : break;
532 : case FC_AT2 :
533 : {
534 0 : if ( nParameters == 2 )
535 0 : aEquation = "(10800000*atan2(" + sParameters[ 1 ] + ","
536 0 : + sParameters[ 0 ] + "))/pi";
537 : }
538 0 : break;
539 : case FC_CAT2 :
540 : {
541 0 : if ( nParameters == 3 )
542 0 : aEquation = sParameters[ 0 ] + "*(cos(atan2(" +
543 0 : sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
544 : }
545 0 : break;
546 : case FC_COS :
547 : {
548 0 : if ( nParameters == 2 )
549 0 : aEquation = sParameters[ 0 ] + "*cos(pi*(" +
550 0 : sParameters[ 1 ] + ")/10800000)";
551 : }
552 0 : break;
553 : case FC_MAX :
554 : {
555 0 : if ( nParameters == 2 )
556 0 : aEquation = "max(" + sParameters[ 0 ] + "," +
557 0 : sParameters[ 1 ] + ")";
558 : }
559 0 : break;
560 : case FC_MIN :
561 : {
562 0 : if ( nParameters == 2 )
563 0 : aEquation = "min(" + sParameters[ 0 ] + "," +
564 0 : sParameters[ 1 ] + ")";
565 : }
566 0 : break;
567 : case FC_MOD :
568 : {
569 0 : if ( nParameters == 3 )
570 0 : aEquation = "sqrt("
571 0 : + sParameters[ 0 ] + "*" + sParameters[ 0 ] + "+"
572 0 : + sParameters[ 1 ] + "*" + sParameters[ 1 ] + "+"
573 0 : + sParameters[ 2 ] + "*" + sParameters[ 2 ] + ")";
574 : }
575 0 : break;
576 : case FC_PIN :
577 : {
578 0 : if ( nParameters == 3 ) // if(x-y,x,if(y-z,z,y))
579 0 : aEquation = "if(" + sParameters[ 0 ] + "-" + sParameters[ 1 ]
580 0 : + "," + sParameters[ 0 ] + ",if(" + sParameters[ 2 ]
581 0 : + "-" + sParameters[ 1 ] + "," + sParameters[ 1 ]
582 0 : + "," + sParameters[ 2 ] + "))";
583 : }
584 0 : break;
585 : case FC_SAT2 :
586 : {
587 0 : if ( nParameters == 3 )
588 0 : aEquation = sParameters[ 0 ] + "*(sin(atan2(" +
589 0 : sParameters[ 2 ] + "," + sParameters[ 1 ] + ")))";
590 : }
591 0 : break;
592 : case FC_SIN :
593 : {
594 0 : if ( nParameters == 2 )
595 0 : aEquation = sParameters[ 0 ] + "*sin(pi*(" +
596 0 : sParameters[ 1 ] + ")/10800000)";
597 : }
598 0 : break;
599 : case FC_SQRT :
600 : {
601 0 : if ( nParameters == 1 )
602 0 : aEquation = "sqrt(" + sParameters[ 0 ] + ")";
603 : }
604 0 : break;
605 : case FC_TAN :
606 : {
607 0 : if ( nParameters == 2 )
608 0 : aEquation = sParameters[ 0 ] + "*tan(pi*(" +
609 0 : sParameters[ 1 ] + ")/10800000)";
610 : }
611 0 : break;
612 : case FC_VAL :
613 : {
614 0 : if ( nParameters == 1 )
615 0 : aEquation = sParameters[ 0 ];
616 : }
617 0 : break;
618 : default :
619 0 : break;
620 : }
621 0 : }
622 : }
623 0 : return aEquation;
624 : }
625 :
626 0 : ContextHandlerRef GeomGuideListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
627 : {
628 0 : if ( aElementToken == A_TOKEN( gd ) ) // CT_GeomGuide
629 : {
630 0 : CustomShapeGuide aGuide;
631 0 : aGuide.maName = rAttribs.getString( XML_name ).get();
632 0 : aGuide.maFormula = convertToOOEquation( mrCustomShapeProperties, rAttribs.getString( XML_fmla ).get() );
633 0 : mrGuideList.push_back( aGuide );
634 : }
635 0 : return this;
636 : }
637 :
638 :
639 :
640 0 : static const OUString GetGeomGuideName( const OUString& rValue )
641 : {
642 0 : return rValue;
643 : }
644 :
645 :
646 : // CT_AdjPoint2D
647 0 : class AdjPoint2DContext : public ContextHandler2
648 : {
649 : public:
650 : AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D );
651 : };
652 :
653 0 : AdjPoint2DContext::AdjPoint2DContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
654 0 : : ContextHandler2( rParent )
655 : {
656 0 : rAdjPoint2D.First = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_x ).get(), true );
657 0 : rAdjPoint2D.Second = GetAdjCoordinate( rCustomShapeProperties, rAttribs.getString( XML_y ).get(), true );
658 0 : }
659 :
660 :
661 : // CT_XYAdjustHandle
662 0 : 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 0 : XYAdjustHandleContext::XYAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
674 : : ContextHandler2( rParent )
675 : , mrAdjustHandle( rAdjustHandle )
676 0 : , mrCustomShapeProperties( rCustomShapeProperties )
677 : {
678 0 : const OUString aEmptyDefault;
679 0 : if ( rAttribs.hasAttribute( XML_gdRefX ) )
680 : {
681 0 : mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefX, aEmptyDefault ) );
682 : }
683 0 : if ( rAttribs.hasAttribute( XML_minX ) )
684 : {
685 0 : mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minX, aEmptyDefault ), true );
686 : }
687 0 : if ( rAttribs.hasAttribute( XML_maxX ) )
688 : {
689 0 : mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxX, aEmptyDefault ), true );
690 : }
691 0 : if ( rAttribs.hasAttribute( XML_gdRefY ) )
692 : {
693 0 : mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefY, aEmptyDefault ) );
694 : }
695 0 : if ( rAttribs.hasAttribute( XML_minY ) )
696 : {
697 0 : mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minY, aEmptyDefault ), true );
698 : }
699 0 : if ( rAttribs.hasAttribute( XML_maxY ) )
700 : {
701 0 : mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxY, aEmptyDefault ), true );
702 0 : }
703 0 : }
704 :
705 0 : ContextHandlerRef XYAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
706 : {
707 0 : if ( aElementToken == A_TOKEN( pos ) )
708 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
709 0 : return 0;
710 : }
711 :
712 :
713 : // CT_PolarAdjustHandle
714 0 : 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 0 : PolarAdjustHandleContext::PolarAdjustHandleContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, AdjustHandle& rAdjustHandle )
726 : : ContextHandler2( rParent )
727 : , mrAdjustHandle( rAdjustHandle )
728 0 : , mrCustomShapeProperties( rCustomShapeProperties )
729 : {
730 0 : const OUString aEmptyDefault;
731 0 : if ( rAttribs.hasAttribute( XML_gdRefR ) )
732 : {
733 0 : mrAdjustHandle.gdRef1 = GetGeomGuideName( rAttribs.getString( XML_gdRefR, aEmptyDefault ) );
734 : }
735 0 : if ( rAttribs.hasAttribute( XML_minR ) )
736 : {
737 0 : mrAdjustHandle.min1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minR, aEmptyDefault ), true );
738 : }
739 0 : if ( rAttribs.hasAttribute( XML_maxR ) )
740 : {
741 0 : mrAdjustHandle.max1 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxR, aEmptyDefault ), true );
742 : }
743 0 : if ( rAttribs.hasAttribute( XML_gdRefAng ) )
744 : {
745 0 : mrAdjustHandle.gdRef2 = GetGeomGuideName( rAttribs.getString( XML_gdRefAng, aEmptyDefault ) );
746 : }
747 0 : if ( rAttribs.hasAttribute( XML_minAng ) )
748 : {
749 0 : mrAdjustHandle.min2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_minAng, aEmptyDefault ) );
750 : }
751 0 : if ( rAttribs.hasAttribute( XML_maxAng ) )
752 : {
753 0 : mrAdjustHandle.max2 = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_maxAng, aEmptyDefault ) );
754 0 : }
755 0 : }
756 :
757 0 : ContextHandlerRef PolarAdjustHandleContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
758 : {
759 0 : if ( aElementToken == A_TOKEN( pos ) )
760 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandle.pos ); // CT_AdjPoint2D
761 0 : return 0;
762 : }
763 :
764 :
765 : // CT_AdjustHandleList
766 0 : 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 0 : AdjustHandleListContext::AdjustHandleListContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, std::vector< AdjustHandle >& rAdjustHandleList )
778 : : ContextHandler2( rParent )
779 : , mrAdjustHandleList( rAdjustHandleList )
780 0 : , mrCustomShapeProperties( rCustomShapeProperties )
781 : {
782 0 : }
783 :
784 0 : ContextHandlerRef AdjustHandleListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
785 : {
786 0 : if ( aElementToken == A_TOKEN( ahXY ) ) // CT_XYAdjustHandle
787 : {
788 0 : AdjustHandle aAdjustHandle( false );
789 0 : mrAdjustHandleList.push_back( aAdjustHandle );
790 0 : return new XYAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
791 : }
792 0 : else if ( aElementToken == A_TOKEN( ahPolar ) ) // CT_PolarAdjustHandle
793 : {
794 0 : AdjustHandle aAdjustHandle( true );
795 0 : mrAdjustHandleList.push_back( aAdjustHandle );
796 0 : return new PolarAdjustHandleContext( *this, rAttribs, mrCustomShapeProperties, mrAdjustHandleList.back() );
797 : }
798 0 : return 0;
799 : }
800 :
801 :
802 : // CT_ConnectionSite
803 0 : 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 0 : ConnectionSiteContext::ConnectionSiteContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties, ConnectionSite& rConnectionSite )
815 : : ContextHandler2( rParent )
816 : , mrConnectionSite( rConnectionSite )
817 0 : , mrCustomShapeProperties( rCustomShapeProperties )
818 : {
819 0 : mrConnectionSite.ang = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_ang ).get() );
820 0 : }
821 :
822 0 : ContextHandlerRef ConnectionSiteContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
823 : {
824 0 : if ( aElementToken == A_TOKEN( pos ) )
825 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrConnectionSite.pos ); // CT_AdjPoint2D
826 0 : return 0;
827 : }
828 :
829 :
830 : // CT_Path2DMoveTo
831 0 : 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 0 : Path2DMoveToContext::Path2DMoveToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
843 : : ContextHandler2( rParent )
844 : , mrAdjPoint2D( rAdjPoint2D )
845 0 : , mrCustomShapeProperties( rCustomShapeProperties )
846 : {
847 0 : }
848 :
849 0 : ContextHandlerRef Path2DMoveToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
850 : {
851 0 : if ( aElementToken == A_TOKEN( pt ) )
852 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
853 0 : return 0;
854 : }
855 :
856 :
857 : // CT_Path2DLineTo
858 0 : 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 0 : Path2DLineToContext::Path2DLineToContext( ContextHandler2Helper& rParent, CustomShapeProperties& rCustomShapeProperties, EnhancedCustomShapeParameterPair& rAdjPoint2D )
870 : : ContextHandler2( rParent )
871 : , mrAdjPoint2D( rAdjPoint2D )
872 0 : , mrCustomShapeProperties( rCustomShapeProperties )
873 : {
874 0 : }
875 :
876 0 : ContextHandlerRef Path2DLineToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
877 : {
878 0 : if ( aElementToken == A_TOKEN( pt ) )
879 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, mrAdjPoint2D ); // CT_AdjPoint2D
880 0 : return 0;
881 : }
882 :
883 :
884 : // CT_Path2DQuadBezierTo
885 0 : 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 0 : 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 0 : , mrCustomShapeProperties( rCustomShapeProperties )
907 : {
908 0 : }
909 :
910 0 : ContextHandlerRef Path2DQuadBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
911 : {
912 0 : if ( aElementToken == A_TOKEN( pt ) )
913 0 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties, nCount++ ? mrPt2 : mrPt1 ); // CT_AdjPoint2D
914 0 : return 0;
915 : }
916 :
917 :
918 : // CT_Path2DCubicBezierTo
919 0 : 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 0 : 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 0 : , nCount( 0 )
944 : {
945 0 : }
946 :
947 0 : ContextHandlerRef Path2DCubicBezierToContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
948 : {
949 0 : if ( aElementToken == A_TOKEN( pt ) )
950 : return new AdjPoint2DContext( *this, rAttribs, mrCustomShapeProperties,
951 0 : 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 0 : 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 0 : , mrCustomShapeProperties( rCustomShapeProperties )
976 : {
977 0 : const OUString aEmptyString;
978 :
979 0 : rPath2D.w = rAttribs.getString( XML_w, aEmptyString ).toInt64();
980 0 : rPath2D.h = rAttribs.getString( XML_h, aEmptyString ).toInt64();
981 0 : rPath2D.fill = rAttribs.getToken( XML_fill, XML_norm );
982 0 : rPath2D.stroke = rAttribs.getBool( XML_stroke, true );
983 0 : rPath2D.extrusionOk = rAttribs.getBool( XML_extrusionOk, true );
984 0 : }
985 :
986 0 : Path2DContext::~Path2DContext()
987 : {
988 0 : EnhancedCustomShapeSegment aNewSegment;
989 0 : switch ( mrPath2D.fill )
990 : {
991 : case XML_none:
992 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
993 0 : break;
994 : case XML_darken:
995 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKEN;
996 0 : break;
997 : case XML_darkenLess:
998 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::DARKENLESS;
999 0 : break;
1000 : case XML_lighten:
1001 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTEN;
1002 0 : break;
1003 : case XML_lightenLess:
1004 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
1005 0 : break;
1006 : }
1007 0 : if (mrPath2D.fill != XML_norm) {
1008 0 : aNewSegment.Count = 0;
1009 0 : mrSegments.push_back( aNewSegment );
1010 : }
1011 0 : if ( !mrPath2D.stroke )
1012 : {
1013 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
1014 0 : aNewSegment.Count = 0;
1015 0 : mrSegments.push_back( aNewSegment );
1016 : }
1017 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
1018 0 : aNewSegment.Count = 0;
1019 0 : mrSegments.push_back( aNewSegment );
1020 0 : }
1021 :
1022 0 : ContextHandlerRef Path2DContext::onCreateContext( sal_Int32 aElementToken,
1023 : const AttributeList& rAttribs )
1024 : {
1025 0 : 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 0 : if ( mrSegments.empty() || ( mrSegments.back().Command != EnhancedCustomShapeSegmentCommand::MOVETO ) ) {
1031 0 : EnhancedCustomShapeSegment aNewSegment;
1032 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
1033 0 : aNewSegment.Count = 0;
1034 0 : mrSegments.push_back( aNewSegment );
1035 : }
1036 : }
1037 0 : break;
1038 : case A_TOKEN( moveTo ) :
1039 : {
1040 0 : EnhancedCustomShapeSegment aNewSegment;
1041 0 : aNewSegment.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
1042 0 : aNewSegment.Count = 1;
1043 0 : mrSegments.push_back( aNewSegment );
1044 :
1045 0 : EnhancedCustomShapeParameterPair aAdjPoint2D;
1046 0 : mrPath2D.parameter.push_back( aAdjPoint2D );
1047 0 : return new Path2DMoveToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1048 : }
1049 : break;
1050 : case A_TOKEN( lnTo ) :
1051 : {
1052 0 : if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::LINETO ) )
1053 0 : mrSegments.back().Count++;
1054 : else
1055 : {
1056 0 : EnhancedCustomShapeSegment aSegment;
1057 0 : aSegment.Command = EnhancedCustomShapeSegmentCommand::LINETO;
1058 0 : aSegment.Count = 1;
1059 0 : mrSegments.push_back( aSegment );
1060 : }
1061 0 : EnhancedCustomShapeParameterPair aAdjPoint2D;
1062 0 : mrPath2D.parameter.push_back( aAdjPoint2D );
1063 0 : return new Path2DLineToContext( *this, mrCustomShapeProperties, mrPath2D.parameter.back() );
1064 : }
1065 : break;
1066 : case A_TOKEN( arcTo ) : // CT_Path2DArcTo
1067 : {
1068 0 : if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::ARCANGLETO ) )
1069 0 : mrSegments.back().Count++;
1070 : else
1071 : {
1072 0 : EnhancedCustomShapeSegment aSegment;
1073 0 : aSegment.Command = EnhancedCustomShapeSegmentCommand::ARCANGLETO;
1074 0 : aSegment.Count = 1;
1075 0 : mrSegments.push_back( aSegment );
1076 : }
1077 :
1078 0 : EnhancedCustomShapeParameterPair aScale;
1079 0 : EnhancedCustomShapeParameterPair aAngles;
1080 :
1081 0 : aScale.First = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_wR ).get(), true );
1082 0 : aScale.Second = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_hR ).get(), true );
1083 :
1084 0 : CustomShapeGuide aGuide;
1085 0 : sal_Int32 nArcNum = mrCustomShapeProperties.getArcNum();
1086 :
1087 : // start angle
1088 0 : aGuide.maName = "arctosa" + OUString::number( nArcNum );
1089 0 : aGuide.maFormula = "("
1090 0 : + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_stAng ).get() ) )
1091 0 : + ")/60000.0";
1092 0 : aAngles.First.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide ) );
1093 0 : aAngles.First.Type = EnhancedCustomShapeParameterType::EQUATION;
1094 :
1095 : // swing angle
1096 0 : aGuide.maName = "arctosw" + OUString::number( nArcNum );
1097 0 : aGuide.maFormula = "("
1098 0 : + GetFormulaParameter( GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_swAng ).get() ) )
1099 0 : + ")/60000.0";
1100 0 : aAngles.Second.Value = Any( CustomShapeProperties::SetCustomShapeGuideValue( mrCustomShapeProperties.getGuideList(), aGuide ) );
1101 0 : aAngles.Second.Type = EnhancedCustomShapeParameterType::EQUATION;
1102 :
1103 0 : mrPath2D.parameter.push_back( aScale );
1104 0 : mrPath2D.parameter.push_back( aAngles );
1105 : }
1106 0 : break;
1107 : case A_TOKEN( quadBezTo ) :
1108 : {
1109 0 : if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO ) )
1110 0 : mrSegments.back().Count++;
1111 : else
1112 : {
1113 0 : EnhancedCustomShapeSegment aSegment;
1114 0 : aSegment.Command = EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
1115 0 : aSegment.Count = 1;
1116 0 : mrSegments.push_back( aSegment );
1117 : }
1118 0 : EnhancedCustomShapeParameterPair aPt1;
1119 0 : EnhancedCustomShapeParameterPair aPt2;
1120 0 : mrPath2D.parameter.push_back( aPt1 );
1121 0 : mrPath2D.parameter.push_back( aPt2 );
1122 : return new Path2DQuadBezierToContext( *this, mrCustomShapeProperties,
1123 0 : mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1124 0 : mrPath2D.parameter.back() );
1125 : }
1126 : break;
1127 : case A_TOKEN( cubicBezTo ) :
1128 : {
1129 0 : if ( !mrSegments.empty() && ( mrSegments.back().Command == EnhancedCustomShapeSegmentCommand::CURVETO ) )
1130 0 : mrSegments.back().Count++;
1131 : else
1132 : {
1133 0 : EnhancedCustomShapeSegment aSegment;
1134 0 : aSegment.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
1135 0 : aSegment.Count = 1;
1136 0 : mrSegments.push_back( aSegment );
1137 : }
1138 0 : EnhancedCustomShapeParameterPair aControlPt1;
1139 0 : EnhancedCustomShapeParameterPair aControlPt2;
1140 0 : EnhancedCustomShapeParameterPair aEndPt;
1141 0 : mrPath2D.parameter.push_back( aControlPt1 );
1142 0 : mrPath2D.parameter.push_back( aControlPt2 );
1143 0 : mrPath2D.parameter.push_back( aEndPt );
1144 : return new Path2DCubicBezierToContext( *this, mrCustomShapeProperties,
1145 0 : mrPath2D.parameter[ mrPath2D.parameter.size() - 3 ],
1146 0 : mrPath2D.parameter[ mrPath2D.parameter.size() - 2 ],
1147 0 : mrPath2D.parameter.back() );
1148 : }
1149 : break;
1150 : }
1151 0 : return 0;
1152 : }
1153 :
1154 :
1155 : // CT_Path2DList
1156 0 : 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 0 : 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 0 : , mrPath2DList( rPath2DList )
1177 : {
1178 0 : }
1179 :
1180 0 : ContextHandlerRef Path2DListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1181 : {
1182 0 : if ( aElementToken == A_TOKEN( path ) )
1183 : {
1184 0 : Path2D aPath2D;
1185 0 : mrPath2DList.push_back( aPath2D );
1186 0 : return new Path2DContext( *this, rAttribs, mrCustomShapeProperties, mrSegments, mrPath2DList.back() );
1187 : }
1188 0 : return 0;
1189 : }
1190 :
1191 :
1192 : // CT_CustomGeometry2D
1193 0 : CustomShapeGeometryContext::CustomShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& /* rAttribs */, CustomShapeProperties& rCustomShapeProperties )
1194 : : ContextHandler2( rParent )
1195 0 : , mrCustomShapeProperties( rCustomShapeProperties )
1196 : {
1197 0 : }
1198 :
1199 0 : ContextHandlerRef CustomShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
1200 : {
1201 0 : switch( aElementToken )
1202 : {
1203 : case A_TOKEN( avLst ): // CT_GeomGuideList adjust value list
1204 0 : return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustmentGuideList() );
1205 : case A_TOKEN( gdLst ): // CT_GeomGuideList guide list
1206 0 : return new GeomGuideListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getGuideList() );
1207 : case A_TOKEN( ahLst ): // CT_AdjustHandleList adjust handle list
1208 0 : return new AdjustHandleListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getAdjustHandleList() );
1209 : case A_TOKEN( cxnLst ): // CT_ConnectionSiteList connection site list
1210 0 : return this;
1211 : case A_TOKEN( rect ): // CT_GeomRectList geometry rect list
1212 : {
1213 0 : GeomRect aGeomRect;
1214 0 : aGeomRect.l = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_l ).get(), true );
1215 0 : aGeomRect.t = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_t ).get(), true );
1216 0 : aGeomRect.r = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_r ).get(), true );
1217 0 : aGeomRect.b = GetAdjCoordinate( mrCustomShapeProperties, rAttribs.getString( XML_b ).get(), true );
1218 0 : mrCustomShapeProperties.getTextRect() = aGeomRect;
1219 : }
1220 0 : break;
1221 : case A_TOKEN( pathLst ): // CT_Path2DList 2d path list
1222 0 : return new Path2DListContext( *this, mrCustomShapeProperties, mrCustomShapeProperties.getSegments(), mrCustomShapeProperties.getPath2DList() );
1223 :
1224 : // from cxnLst:
1225 : case A_TOKEN( cxn ): // CT_ConnectionSite
1226 : {
1227 0 : ConnectionSite aConnectionSite;
1228 0 : mrCustomShapeProperties.getConnectionSiteList().push_back( aConnectionSite );
1229 0 : return new ConnectionSiteContext( *this, rAttribs, mrCustomShapeProperties, mrCustomShapeProperties.getConnectionSiteList().back() );
1230 : }
1231 : }
1232 0 : return 0;
1233 : }
1234 :
1235 :
1236 : // CT_PresetGeometry2D
1237 0 : PresetShapeGeometryContext::PresetShapeGeometryContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, CustomShapeProperties& rCustomShapeProperties )
1238 : : ContextHandler2( rParent )
1239 0 : , mrCustomShapeProperties( rCustomShapeProperties )
1240 : {
1241 0 : sal_Int32 nShapeType = rAttribs.getToken( XML_prst, FastToken::DONTKNOW );
1242 : OSL_ENSURE( nShapeType != FastToken::DONTKNOW, "oox::drawingml::CustomShapeCustomGeometryContext::CustomShapeCustomGeometryContext(), unknown shape type" );
1243 0 : mrCustomShapeProperties.setShapePresetType( nShapeType );
1244 0 : }
1245 :
1246 0 : ContextHandlerRef PresetShapeGeometryContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
1247 : {
1248 0 : if ( aElementToken == A_TOKEN( avLst ) )
1249 0 : 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 0 : } }
1274 :
1275 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|