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