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 "svx/EnhancedCustomShape2d.hxx"
21 : #include "svx/EnhancedCustomShapeGeometry.hxx"
22 : #include "svx/EnhancedCustomShapeTypeNames.hxx"
23 : #include <svx/svdoashp.hxx>
24 : #include <svx/svdtrans.hxx>
25 : #include <svx/svdocirc.hxx>
26 : #include <svx/svdogrp.hxx>
27 : #include <svx/svdopath.hxx>
28 : #include <svx/svdocapt.hxx>
29 : #include <svx/svdpage.hxx>
30 : #include <svx/xflclit.hxx>
31 : #include <svx/sdasaitm.hxx>
32 : #include <svx/svdmodel.hxx>
33 : #include <rtl/crc.h>
34 : #include <rtl/math.hxx>
35 : #include <svx/xfillit0.hxx>
36 : #include <svx/xlnstit.hxx>
37 : #include <svx/xlnedit.hxx>
38 : #include <svx/xlnstwit.hxx>
39 : #include <svx/xlnedwit.hxx>
40 : #include <svx/xlnstcit.hxx>
41 : #include <svx/xlnedcit.hxx>
42 : #include <svx/xflgrit.hxx>
43 : #include <svx/xflhtit.hxx>
44 : #include <svx/xbtmpit.hxx>
45 : #include <svx/xgrad.hxx>
46 : #include <svx/xhatch.hxx>
47 : #include <com/sun/star/awt/Size.hpp>
48 : #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
49 : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
50 : #include <boost/shared_ptr.hpp>
51 : #include <basegfx/numeric/ftools.hxx>
52 : #include <basegfx/color/bcolortools.hxx>
53 : #include <basegfx/polygon/b2dpolygon.hxx>
54 : #include <basegfx/polygon/b2dpolygontools.hxx>
55 : #include <rtl/strbuf.hxx>
56 : #include <math.h>
57 :
58 : using namespace ::com::sun::star;
59 : using namespace ::com::sun::star::uno;
60 : using namespace ::com::sun::star::drawing;
61 : using namespace ::com::sun::star::drawing::EnhancedCustomShapeSegmentCommand;
62 :
63 29948 : void EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( EnhancedCustomShapeParameter& rParameter, const sal_Int32 nValue )
64 : {
65 29948 : sal_uInt32 nDat = (sal_uInt32)nValue;
66 29948 : sal_Int32 nNewValue = nValue;
67 :
68 : // check if this is a special point
69 29948 : if ( ( nDat >> 16 ) == 0x8000 )
70 : {
71 3018 : nNewValue = (sal_uInt16)nDat;
72 3018 : rParameter.Type = EnhancedCustomShapeParameterType::EQUATION;
73 : }
74 : else
75 26930 : rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
76 29948 : rParameter.Value <<= nNewValue;
77 29948 : }
78 :
79 2962 : OUString EnhancedCustomShape2d::GetEquation( const sal_uInt16 nFlags, sal_Int32 nP1, sal_Int32 nP2, sal_Int32 nP3 )
80 : {
81 2962 : OUString aEquation;
82 2962 : bool b1Special = ( nFlags & 0x2000 ) != 0;
83 2962 : bool b2Special = ( nFlags & 0x4000 ) != 0;
84 2962 : bool b3Special = ( nFlags & 0x8000 ) != 0;
85 2962 : switch( nFlags & 0xff )
86 : {
87 : case 0 :
88 : case 14 :
89 : {
90 1308 : sal_Int32 nOptimize = 0;
91 1308 : if ( nP1 )
92 1282 : nOptimize |= 1;
93 1308 : if ( nP2 )
94 380 : nOptimize |= 2;
95 1308 : if ( b1Special )
96 950 : nOptimize |= 4;
97 1308 : if ( b2Special )
98 184 : nOptimize |= 8;
99 1308 : switch( nOptimize )
100 : {
101 : case 0 :
102 0 : break;
103 : case 1 :
104 : case 4 :
105 : case 5 :
106 928 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
107 928 : break;
108 : case 2 :
109 : case 8 :
110 : case 10:
111 26 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
112 26 : break;
113 : default :
114 : {
115 354 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
116 354 : aEquation += OUString( (sal_Unicode)'+' );
117 354 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
118 : }
119 354 : break;
120 : }
121 1308 : if ( b3Special || nP3 )
122 : {
123 674 : aEquation += OUString( (sal_Unicode)'-' );
124 674 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
125 : }
126 : }
127 1308 : break;
128 : case 1 :
129 : {
130 346 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
131 346 : if ( b2Special || ( nP2 != 1 ) )
132 : {
133 252 : aEquation += OUString( (sal_Unicode)'*' );
134 252 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
135 : }
136 346 : if ( b3Special || ( ( nP3 != 1 ) && ( nP3 != 0 ) ) )
137 : {
138 248 : aEquation += OUString( (sal_Unicode)'/' );
139 248 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
140 : }
141 : }
142 346 : break;
143 : case 2 :
144 : {
145 12 : aEquation += "(";
146 12 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
147 12 : aEquation += "+";
148 12 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
149 12 : aEquation += ")/2";
150 : }
151 12 : break;
152 : case 3 :
153 : {
154 76 : aEquation += "abs(";
155 76 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
156 76 : aEquation += ")";
157 : }
158 76 : break;
159 : case 4 :
160 : {
161 0 : aEquation += "min(";
162 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
163 0 : aEquation += ",";
164 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
165 0 : aEquation += ")";
166 : }
167 0 : break;
168 : case 5 :
169 : {
170 0 : aEquation += "max(";
171 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
172 0 : aEquation += ",";
173 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
174 0 : aEquation += ")";
175 : }
176 0 : break;
177 : case 6 :
178 : {
179 460 : aEquation += "if(";
180 460 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
181 460 : aEquation += OUString( (sal_Unicode)',' );
182 460 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
183 460 : aEquation += OUString( (sal_Unicode)',' );
184 460 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
185 460 : aEquation += OUString( (sal_Unicode)')' );
186 : }
187 460 : break;
188 : case 7 :
189 : {
190 0 : aEquation += "sqrt(";
191 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
192 0 : aEquation += "*";
193 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
194 0 : aEquation += "+";
195 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
196 0 : aEquation += "*";
197 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
198 0 : aEquation += "+";
199 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
200 0 : aEquation += "*";
201 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
202 0 : aEquation += OUString( (sal_Unicode)')' );
203 : }
204 0 : break;
205 : case 8 :
206 : {
207 6 : aEquation += "atan2(";
208 6 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
209 6 : aEquation += ",";
210 6 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
211 6 : aEquation += ")/(pi/180)";
212 : }
213 6 : break;
214 : case 9 :
215 : {
216 50 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
217 50 : aEquation += "*sin(";
218 50 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
219 50 : aEquation += "*(pi/180))";
220 : }
221 50 : break;
222 : case 10 :
223 : {
224 36 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
225 36 : aEquation += "*cos(";
226 36 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
227 36 : aEquation += "*(pi/180))";
228 : }
229 36 : break;
230 : case 11 :
231 : {
232 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
233 0 : aEquation += "*cos(atan2(";
234 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
235 0 : aEquation += ",";
236 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
237 0 : aEquation += "))";
238 : }
239 0 : break;
240 : case 12 :
241 : {
242 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
243 0 : aEquation += "*sin(atan2(";
244 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
245 0 : aEquation += ",";
246 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
247 0 : aEquation += "))";
248 : }
249 0 : break;
250 : case 13 :
251 : {
252 12 : aEquation += "sqrt(";
253 12 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
254 12 : aEquation += ")";
255 : }
256 12 : break;
257 : case 15 :
258 : {
259 24 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
260 24 : aEquation += "*sqrt(1-(";
261 24 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
262 24 : aEquation += "/";
263 24 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
264 24 : aEquation += ")";
265 24 : aEquation += "*(";
266 24 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
267 24 : aEquation += "/";
268 24 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
269 24 : aEquation += "))";
270 : }
271 24 : break;
272 : case 16 :
273 : {
274 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
275 0 : aEquation += "*tan(";
276 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
277 0 : aEquation += ")";
278 : }
279 0 : break;
280 : case 0x80 :
281 : {
282 0 : aEquation += "sqrt(";
283 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
284 0 : aEquation += "*";
285 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
286 0 : aEquation += "-";
287 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
288 0 : aEquation += "*";
289 0 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
290 0 : aEquation += OUString( (sal_Unicode)')' );
291 : }
292 0 : break;
293 : case 0x81 :
294 : {
295 318 : aEquation += "(cos(";
296 318 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
297 318 : aEquation += "*(pi/180))*(";
298 318 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
299 318 : aEquation += "-10800)+sin(";
300 318 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
301 318 : aEquation += "*(pi/180))*(";
302 318 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
303 318 : aEquation += "-10800))+10800";
304 : }
305 318 : break;
306 : case 0x82 :
307 : {
308 314 : aEquation += "-(sin(";
309 314 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
310 314 : aEquation += "*(pi/180))*(";
311 314 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special );
312 314 : aEquation += "-10800)-cos(";
313 314 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special );
314 314 : aEquation += "*(pi/180))*(";
315 314 : EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special );
316 314 : aEquation += "-10800))+10800";
317 : }
318 314 : break;
319 : }
320 2962 : return aEquation;
321 : }
322 :
323 7506 : void EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( OUString& rParameter, const sal_Int32 nPara, const bool bIsSpecialValue )
324 : {
325 7506 : if ( bIsSpecialValue )
326 : {
327 3656 : if ( nPara & 0x400 )
328 : {
329 2594 : rParameter += "?";
330 2594 : rParameter += OUString::number( ( nPara & 0xff ) );
331 2594 : rParameter += " ";
332 : }
333 : else
334 : {
335 1062 : switch( nPara )
336 : {
337 : case DFF_Prop_adjustValue :
338 : case DFF_Prop_adjust2Value :
339 : case DFF_Prop_adjust3Value :
340 : case DFF_Prop_adjust4Value :
341 : case DFF_Prop_adjust5Value :
342 : case DFF_Prop_adjust6Value :
343 : case DFF_Prop_adjust7Value :
344 : case DFF_Prop_adjust8Value :
345 : case DFF_Prop_adjust9Value :
346 : case DFF_Prop_adjust10Value :
347 : {
348 902 : rParameter += "$";
349 902 : rParameter += OUString::number( ( nPara - DFF_Prop_adjustValue ) );
350 902 : rParameter += " ";
351 : }
352 902 : break;
353 : case DFF_Prop_geoLeft :
354 : {
355 32 : rParameter += "left";
356 : }
357 32 : break;
358 : case DFF_Prop_geoTop :
359 : {
360 32 : rParameter += "top";
361 : }
362 32 : break;
363 : case DFF_Prop_geoRight :
364 : {
365 46 : rParameter += "right";
366 : }
367 46 : break;
368 : case DFF_Prop_geoBottom :
369 : {
370 50 : rParameter += "bottom";
371 : }
372 50 : break;
373 : }
374 : }
375 : }
376 : else
377 : {
378 3850 : rParameter += OUString::number( ( nPara ) );
379 : }
380 7506 : }
381 :
382 920 : void EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( EnhancedCustomShapeParameter& rParameter, const sal_Int32 nPara, const bool bIsSpecialValue, bool bHorz )
383 : {
384 920 : sal_Int32 nValue = 0;
385 920 : if ( bIsSpecialValue )
386 : {
387 516 : if ( ( nPara >= 0x100 ) && ( nPara <= 0x107 ) )
388 : {
389 286 : nValue = nPara & 0xff;
390 286 : rParameter.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
391 : }
392 230 : else if ( ( nPara >= 3 ) && ( nPara <= 0x82 ) )
393 : {
394 36 : nValue = nPara - 3;
395 36 : rParameter.Type = EnhancedCustomShapeParameterType::EQUATION;
396 : }
397 194 : else if ( nPara == 0 )
398 : {
399 48 : nValue = 0;
400 48 : if ( bHorz )
401 14 : rParameter.Type = EnhancedCustomShapeParameterType::LEFT;
402 : else
403 34 : rParameter.Type = EnhancedCustomShapeParameterType::TOP;
404 : }
405 146 : else if ( nPara == 1 )
406 : {
407 6 : nValue = 0;
408 6 : if ( bHorz )
409 6 : rParameter.Type = EnhancedCustomShapeParameterType::RIGHT;
410 : else
411 0 : rParameter.Type = EnhancedCustomShapeParameterType::BOTTOM;
412 : }
413 140 : else if ( nPara == 2 ) // means to be centered, but should not be
414 : { // used in our implementation
415 0 : nValue = 5600;
416 0 : rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
417 : }
418 : else
419 : {
420 140 : nValue = nPara;
421 140 : rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
422 : }
423 : }
424 : else
425 : {
426 404 : nValue = nPara;
427 404 : rParameter.Type = EnhancedCustomShapeParameterType::NORMAL;
428 : }
429 920 : rParameter.Value <<= nValue;
430 920 : }
431 :
432 130 : bool EnhancedCustomShape2d::ConvertSequenceToEnhancedCustomShape2dHandle(
433 : const com::sun::star::beans::PropertyValues& rHandleProperties,
434 : EnhancedCustomShape2d::Handle& rDestinationHandle )
435 : {
436 130 : bool bRetValue = false;
437 130 : sal_uInt32 i, nProperties = rHandleProperties.getLength();
438 130 : if ( nProperties )
439 : {
440 130 : rDestinationHandle.nFlags = 0;
441 654 : for ( i = 0; i < nProperties; i++ )
442 : {
443 524 : const com::sun::star::beans::PropertyValue& rPropVal = rHandleProperties[ i ];
444 :
445 524 : if ( rPropVal.Name == "Position" )
446 : {
447 130 : if ( rPropVal.Value >>= rDestinationHandle.aPosition )
448 130 : bRetValue = true;
449 : }
450 394 : else if ( rPropVal.Name == "MirroredX" )
451 : {
452 : bool bMirroredX;
453 0 : if ( rPropVal.Value >>= bMirroredX )
454 : {
455 0 : if ( bMirroredX )
456 0 : rDestinationHandle.nFlags |= HANDLE_FLAGS_MIRRORED_X;
457 : }
458 : }
459 394 : else if ( rPropVal.Name == "MirroredY" )
460 : {
461 : bool bMirroredY;
462 0 : if ( rPropVal.Value >>= bMirroredY )
463 : {
464 0 : if ( bMirroredY )
465 0 : rDestinationHandle.nFlags |= HANDLE_FLAGS_MIRRORED_Y;
466 : }
467 : }
468 394 : else if ( rPropVal.Name == "Switched" )
469 : {
470 : bool bSwitched;
471 0 : if ( rPropVal.Value >>= bSwitched )
472 : {
473 0 : if ( bSwitched )
474 0 : rDestinationHandle.nFlags |= HANDLE_FLAGS_SWITCHED;
475 : }
476 : }
477 394 : else if ( rPropVal.Name == "Polar" )
478 : {
479 0 : if ( rPropVal.Value >>= rDestinationHandle.aPolar )
480 0 : rDestinationHandle.nFlags |= HANDLE_FLAGS_POLAR;
481 : }
482 394 : else if ( rPropVal.Name == "RefX" )
483 : {
484 110 : if ( rPropVal.Value >>= rDestinationHandle.nRefX )
485 110 : rDestinationHandle.nFlags |= HANDLE_FLAGS_REFX;
486 : }
487 284 : else if ( rPropVal.Name == "RefY" )
488 : {
489 16 : if ( rPropVal.Value >>= rDestinationHandle.nRefY )
490 16 : rDestinationHandle.nFlags |= HANDLE_FLAGS_REFY;
491 : }
492 268 : else if ( rPropVal.Name == "RefAngle" )
493 : {
494 0 : if ( rPropVal.Value >>= rDestinationHandle.nRefAngle )
495 0 : rDestinationHandle.nFlags |= HANDLE_FLAGS_REFANGLE;
496 : }
497 268 : else if ( rPropVal.Name == "RefR" )
498 : {
499 0 : if ( rPropVal.Value >>= rDestinationHandle.nRefR )
500 0 : rDestinationHandle.nFlags |= HANDLE_FLAGS_REFR;
501 : }
502 268 : else if ( rPropVal.Name == "RadiusRangeMinimum" )
503 : {
504 0 : if ( rPropVal.Value >>= rDestinationHandle.aRadiusRangeMinimum )
505 0 : rDestinationHandle.nFlags |= HANDLE_FLAGS_RADIUS_RANGE_MINIMUM;
506 : }
507 268 : else if ( rPropVal.Name == "RadiusRangeMaximum" )
508 : {
509 0 : if ( rPropVal.Value >>= rDestinationHandle.aRadiusRangeMaximum )
510 0 : rDestinationHandle.nFlags |= HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM;
511 : }
512 268 : else if ( rPropVal.Name == "RangeXMinimum" )
513 : {
514 114 : if ( rPropVal.Value >>= rDestinationHandle.aXRangeMinimum )
515 114 : rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_X_MINIMUM;
516 : }
517 154 : else if ( rPropVal.Name == "RangeXMaximum" )
518 : {
519 114 : if ( rPropVal.Value >>= rDestinationHandle.aXRangeMaximum )
520 114 : rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_X_MAXIMUM;
521 : }
522 40 : else if ( rPropVal.Name == "RangeYMinimum" )
523 : {
524 20 : if ( rPropVal.Value >>= rDestinationHandle.aYRangeMinimum )
525 20 : rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_Y_MINIMUM;
526 : }
527 20 : else if ( rPropVal.Name == "RangeYMaximum" )
528 : {
529 20 : if ( rPropVal.Value >>= rDestinationHandle.aYRangeMaximum )
530 20 : rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_Y_MAXIMUM;
531 : }
532 : }
533 : }
534 130 : return bRetValue;
535 : }
536 :
537 41610 : const sal_Int32* EnhancedCustomShape2d::ApplyShapeAttributes( const SdrCustomShapeGeometryItem& rGeometryItem )
538 : {
539 41610 : const sal_Int32* pDefData = NULL;
540 41610 : const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
541 41610 : if ( pDefCustomShape )
542 17488 : pDefData = pDefCustomShape->pDefData;
543 :
544 :
545 : // AdjustmentValues
546 41610 : const Any* pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "AdjustmentValues" );
547 41610 : if ( pAny )
548 29606 : *pAny >>= seqAdjustmentValues;
549 :
550 :
551 : // Coordsize
552 41610 : const Any* pViewBox = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "ViewBox" );
553 41610 : com::sun::star::awt::Rectangle aViewBox;
554 41610 : if ( pViewBox && (*pViewBox >>= aViewBox ) )
555 : {
556 27958 : nCoordLeft = aViewBox.X;
557 27958 : nCoordTop = aViewBox.Y;
558 27958 : nCoordWidthG = labs( aViewBox.Width );
559 27958 : nCoordHeightG = labs( aViewBox.Height);
560 : }
561 41610 : const OUString sPath( "Path" );
562 :
563 :
564 : // Path/Coordinates
565 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "Coordinates" );
566 41610 : if ( pAny )
567 27958 : *pAny >>= seqCoordinates;
568 :
569 :
570 : // Path/GluePoints
571 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "GluePoints" );
572 41610 : if ( pAny )
573 252 : *pAny >>= seqGluePoints;
574 :
575 :
576 : // Path/Segments
577 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "Segments" );
578 41610 : if ( pAny )
579 24272 : *pAny >>= seqSegments;
580 :
581 :
582 : // Path/SubViewSize
583 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "SubViewSize" );
584 41610 : if ( pAny )
585 1136 : *pAny >>= seqSubViewSize;
586 :
587 :
588 : // Path/StretchX
589 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "StretchX" );
590 41610 : if ( pAny )
591 : {
592 18 : sal_Int32 nStretchX = 0;
593 18 : if ( *pAny >>= nStretchX )
594 18 : nXRef = nStretchX;
595 : }
596 :
597 :
598 : // Path/StretchY
599 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "StretchY" );
600 41610 : if ( pAny )
601 : {
602 18 : sal_Int32 nStretchY = 0;
603 18 : if ( *pAny >>= nStretchY )
604 18 : nYRef = nStretchY;
605 : }
606 :
607 :
608 : // Path/TextFrames
609 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, "TextFrames" );
610 41610 : if ( pAny )
611 23302 : *pAny >>= seqTextFrames;
612 :
613 :
614 : // Equations
615 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "Equations" );
616 41610 : if ( pAny )
617 23278 : *pAny >>= seqEquations;
618 :
619 :
620 : // Handles
621 41610 : pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "Handles" );
622 41610 : if ( pAny )
623 23272 : *pAny >>= seqHandles;
624 :
625 41610 : return pDefData;
626 : }
627 :
628 41610 : EnhancedCustomShape2d::~EnhancedCustomShape2d()
629 : {
630 41610 : }
631 :
632 44676 : void EnhancedCustomShape2d::SetPathSize( sal_Int32 nIndex )
633 : {
634 44676 : sal_Int32 nWidth = 0;
635 44676 : sal_Int32 nHeight = 0;
636 :
637 44676 : if ( seqSubViewSize.getLength() && nIndex < seqSubViewSize.getLength() ) {
638 1774 : nWidth = seqSubViewSize[ nIndex ].Width;
639 1774 : nHeight = seqSubViewSize[ nIndex ].Height;
640 : OSL_TRACE("set subpath %d size: %d x %d", nIndex, nWidth, nHeight);
641 : }
642 :
643 44676 : if ( nWidth && nHeight ) {
644 1774 : nCoordWidth = nWidth;
645 1774 : nCoordHeight = nHeight;
646 : } else {
647 42902 : nCoordWidth = nCoordWidthG;
648 42902 : nCoordHeight = nCoordHeightG;
649 : }
650 :
651 44676 : fXScale = nCoordWidth == 0 ? 0.0 : (double)aLogicRect.GetWidth() / (double)nCoordWidth;
652 44676 : fYScale = nCoordHeight == 0 ? 0.0 : (double)aLogicRect.GetHeight() / (double)nCoordHeight;
653 44676 : if ( bOOXMLShape )
654 : {
655 : OSL_TRACE("ooxml shape, path width: %d height: %d", nCoordWidth, nCoordHeight);
656 24374 : if ( nCoordWidth == 0 )
657 22600 : fXScale = 1.0;
658 24374 : if ( nCoordHeight == 0 )
659 22600 : fYScale = 1.0;
660 : }
661 44676 : if ( (sal_uInt32)nXRef != 0x80000000 && aLogicRect.GetHeight() )
662 : {
663 18 : fXRatio = (double)aLogicRect.GetWidth() / (double)aLogicRect.GetHeight();
664 18 : if ( fXRatio > 1 )
665 18 : fXScale /= fXRatio;
666 : else
667 0 : fXRatio = 1.0;
668 : }
669 : else
670 44658 : fXRatio = 1.0;
671 44676 : if ( (sal_uInt32)nYRef != 0x80000000 && aLogicRect.GetWidth() )
672 : {
673 18 : fYRatio = (double)aLogicRect.GetHeight() / (double)aLogicRect.GetWidth();
674 18 : if ( fYRatio > 1 )
675 0 : fYScale /= fYRatio;
676 : else
677 18 : fYRatio = 1.0;
678 : }
679 : else
680 44658 : fYRatio = 1.0;
681 44676 : }
682 :
683 41610 : EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
684 41610 : SfxItemSet ( pAObj->GetMergedItemSet() ),
685 : pCustomShapeObj ( pAObj ),
686 : eSpType ( mso_sptNil ),
687 : nCoordLeft ( 0 ),
688 : nCoordTop ( 0 ),
689 : nCoordWidthG ( 21600 ),
690 : nCoordHeightG ( 21600 ),
691 : bOOXMLShape ( false ),
692 : nXRef ( 0x80000000 ),
693 : nYRef ( 0x80000000 ),
694 : nFlags ( 0 ),
695 : nColorData ( 0 ),
696 : bTextFlow ( false ),
697 41610 : bFilled ( static_cast<const XFillStyleItem&>(pAObj->GetMergedItem( XATTR_FILLSTYLE )).GetValue() != drawing::FillStyle_NONE ),
698 41610 : bStroked ( static_cast<const XLineStyleItem&>(pAObj->GetMergedItem( XATTR_LINESTYLE )).GetValue() != XLINE_NONE ),
699 : bFlipH ( false ),
700 124830 : bFlipV ( false )
701 : {
702 : // bTextFlow needs to be set before clearing the TextDirection Item
703 :
704 41610 : ClearItem( SDRATTR_TEXTDIRECTION ); //SJ: vertical writing is not required, by removing this item no outliner is created
705 :
706 : // #i105323# For 2D AtoShapes, the shadow attirbute does not need to be applied to any
707 : // of the constucted helper SdrObjects. This would lead to problems since the shadow
708 : // of one helper object would fall on one helper object behind it (e.g. with the
709 : // eyes of the smiley shape). This is not wanted; instead a single shadow 'behind'
710 : // the AutoShape visualisation is wanted. This is done with primitive functionailty
711 : // now in SdrCustomShapePrimitive2D::create2DDecomposition, but only for 2D objects
712 : // (see there and in EnhancedCustomShape3d::Create3DObject to read more).
713 : // This exception may be removed later when AutoShapes will create primitives directly.
714 : // So, currently remove the ShadowAttribute from the ItemSet to not apply it to any
715 : // 2D helper shape.
716 41610 : ClearItem(SDRATTR_SHADOW);
717 :
718 41610 : Point aP( pCustomShapeObj->GetSnapRect().Center() );
719 41610 : Size aS( pCustomShapeObj->GetLogicRect().GetSize() );
720 41610 : aP.X() -= aS.Width() / 2;
721 41610 : aP.Y() -= aS.Height() / 2;
722 41610 : aLogicRect = Rectangle( aP, aS );
723 :
724 41610 : OUString sShapeType;
725 41610 : const SdrCustomShapeGeometryItem& rGeometryItem = static_cast<const SdrCustomShapeGeometryItem&>(pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
726 41610 : const Any* pAny = rGeometryItem.GetPropertyValueByName( "Type" );
727 41610 : if ( pAny ) {
728 29456 : *pAny >>= sShapeType;
729 29456 : bOOXMLShape = ( sShapeType.startsWith("ooxml-") );
730 : OSL_TRACE("shape type: %s %d", OUStringToOString( sShapeType, RTL_TEXTENCODING_ASCII_US ).getStr(), bOOXMLShape);
731 : }
732 41610 : eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
733 :
734 41610 : pAny = rGeometryItem.GetPropertyValueByName( "MirroredX" );
735 41610 : if ( pAny )
736 23362 : *pAny >>= bFlipH;
737 41610 : pAny = rGeometryItem.GetPropertyValueByName( "MirroredY" );
738 41610 : if ( pAny )
739 23430 : *pAny >>= bFlipV;
740 :
741 41610 : if ( pCustomShapeObj->ISA( SdrObjCustomShape ) ) // should always be a SdrObjCustomShape, but you don't know
742 41610 : nRotateAngle = (sal_Int32)(static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetObjectRotation() * 100.0);
743 : else
744 0 : nRotateAngle = pCustomShapeObj->GetRotateAngle();
745 :
746 41610 : /*const sal_Int32* pDefData =*/ ApplyShapeAttributes( rGeometryItem );
747 41610 : SetPathSize();
748 :
749 41610 : switch( eSpType )
750 : {
751 0 : case mso_sptCan : nColorData = 0x20400000; break;
752 0 : case mso_sptCube : nColorData = 0x302e0000; break;
753 0 : case mso_sptActionButtonBlank : nColorData = 0x502ce400; break;
754 0 : case mso_sptActionButtonHome : nColorData = 0x702ce4ce; break;
755 0 : case mso_sptActionButtonHelp : nColorData = 0x602ce4c0; break;
756 0 : case mso_sptActionButtonInformation : nColorData = 0x702ce4c5; break;
757 0 : case mso_sptActionButtonBackPrevious : nColorData = 0x602ce4c0; break;
758 0 : case mso_sptActionButtonForwardNext : nColorData = 0x602ce4c0; break;
759 0 : case mso_sptActionButtonBeginning : nColorData = 0x602ce4c0; break;
760 0 : case mso_sptActionButtonEnd : nColorData = 0x602ce4c0; break;
761 0 : case mso_sptActionButtonReturn : nColorData = 0x602ce4c0; break;
762 0 : case mso_sptActionButtonDocument : nColorData = 0x702ce4ec; break;
763 0 : case mso_sptActionButtonSound : nColorData = 0x602ce4c0; break;
764 0 : case mso_sptActionButtonMovie : nColorData = 0x602ce4c0; break;
765 2 : case mso_sptBevel : nColorData = 0x502ce400; break;
766 0 : case mso_sptFoldedCorner : nColorData = 0x20e00000; break;
767 8 : case mso_sptSmileyFace : nColorData = 0x20e00000; break;
768 : case mso_sptNil :
769 : {
770 33256 : if( sShapeType.getLength() > 4 &&
771 10462 : sShapeType.match( "col-" ))
772 : {
773 0 : nColorData = sShapeType.copy( 4 ).toUInt32( 16 );
774 : }
775 : }
776 22794 : break;
777 : case mso_sptCurvedLeftArrow :
778 : case mso_sptCurvedRightArrow :
779 : case mso_sptCurvedUpArrow :
780 30 : case mso_sptCurvedDownArrow : nColorData = 0x20d00000; break;
781 0 : case mso_sptRibbon2 : nColorData = 0x30ee0000; break;
782 0 : case mso_sptRibbon : nColorData = 0x30ee0000; break;
783 :
784 0 : case mso_sptEllipseRibbon2 : nColorData = 0x30ee0000; break;
785 0 : case mso_sptEllipseRibbon : nColorData = 0x30ee0000; break;
786 :
787 0 : case mso_sptVerticalScroll : nColorData = 0x30ee0000; break;
788 8 : case mso_sptHorizontalScroll : nColorData = 0x30ee0000; break;
789 : default:
790 18768 : break;
791 : }
792 :
793 41610 : sal_Int32 i, nLength = seqEquations.getLength();
794 :
795 41610 : if ( nLength )
796 : {
797 23278 : vNodesSharedPtr.resize( nLength );
798 23278 : vEquationResults.resize( nLength );
799 276930 : for ( i = 0; i < seqEquations.getLength(); i++ )
800 : {
801 253652 : vEquationResults[ i ].bReady = false;
802 : try
803 : {
804 253652 : vNodesSharedPtr[ i ] = EnhancedCustomShape::FunctionParser::parseFunction( seqEquations[ i ], *this );
805 : }
806 0 : catch ( EnhancedCustomShape::ParseError& )
807 : {
808 : OSL_TRACE("error: equation number: %d, parser failed ( %s )",
809 : i, OUStringToOString( seqEquations[ i ], RTL_TEXTENCODING_ASCII_US ).getStr());
810 : }
811 : }
812 41610 : }
813 41610 : }
814 38912 : double EnhancedCustomShape2d::GetEnumFunc( const EnumFunc eFunc ) const
815 : {
816 38912 : double fRet = 0.0;
817 38912 : switch( eFunc )
818 : {
819 1902 : case ENUM_FUNC_PI : fRet = F_PI; break;
820 14 : case ENUM_FUNC_LEFT : fRet = 0.0; break;
821 14 : case ENUM_FUNC_TOP : fRet = 0.0; break;
822 24 : case ENUM_FUNC_RIGHT : fRet = (double)nCoordWidth * fXRatio; break;
823 24 : case ENUM_FUNC_BOTTOM : fRet = (double)nCoordHeight * fYRatio; break;
824 0 : case ENUM_FUNC_XSTRETCH : fRet = nXRef; break;
825 0 : case ENUM_FUNC_YSTRETCH : fRet = nYRef; break;
826 0 : case ENUM_FUNC_HASSTROKE : fRet = bStroked ? 1.0 : 0.0; break;
827 0 : case ENUM_FUNC_HASFILL : fRet = bFilled ? 1.0 : 0.0; break;
828 0 : case ENUM_FUNC_WIDTH : fRet = nCoordWidth; break;
829 0 : case ENUM_FUNC_HEIGHT : fRet = nCoordHeight; break;
830 18352 : case ENUM_FUNC_LOGWIDTH : fRet = aLogicRect.GetWidth(); break;
831 18582 : case ENUM_FUNC_LOGHEIGHT : fRet = aLogicRect.GetHeight(); break;
832 : }
833 38912 : return fRet;
834 : }
835 12732 : double EnhancedCustomShape2d::GetAdjustValueAsDouble( const sal_Int32 nIndex ) const
836 : {
837 12732 : double fNumber = 0.0;
838 12732 : if ( nIndex < seqAdjustmentValues.getLength() )
839 : {
840 12732 : if ( seqAdjustmentValues[ nIndex ].Value.getValueTypeClass() == TypeClass_DOUBLE )
841 0 : seqAdjustmentValues[ nIndex ].Value >>= fNumber;
842 : else
843 : {
844 12732 : sal_Int32 nNumber = 0;
845 12732 : seqAdjustmentValues[ nIndex ].Value >>= nNumber;
846 12732 : fNumber = (double)nNumber;
847 : }
848 : }
849 12732 : return fNumber;
850 : }
851 78976 : double EnhancedCustomShape2d::GetEquationValueAsDouble( const sal_Int32 nIndex ) const
852 : {
853 78976 : double fNumber = 0.0;
854 : #if OSL_DEBUG_LEVEL > 1
855 : static sal_uInt32 nLevel = 0;
856 : #endif
857 78976 : if ( nIndex < (sal_Int32)vNodesSharedPtr.size() )
858 : {
859 78976 : if ( vNodesSharedPtr[ nIndex ].get() ) {
860 : #if OSL_DEBUG_LEVEL > 1
861 : nLevel ++;
862 : #endif
863 : try
864 : {
865 78976 : if ( vEquationResults[ nIndex ].bReady )
866 24196 : fNumber = vEquationResults[ nIndex ].fValue;
867 : else {
868 : // cast to non const, so that we can optimize by caching
869 : // equation results, without changing all the const in the stack
870 54780 : struct EquationResult &aResult = ((EnhancedCustomShape2d*)this)->vEquationResults[ nIndex ];
871 :
872 54780 : fNumber = aResult.fValue = (*vNodesSharedPtr[ nIndex ])();
873 54780 : aResult.bReady = true;
874 :
875 54780 : if ( !rtl::math::isFinite( fNumber ) )
876 0 : fNumber = 0.0;
877 : #if OSL_DEBUG_LEVEL > 1
878 : OSL_TRACE("equation %d (level: %d): %s --> %f (angle: %f)", nIndex,
879 : nLevel, OUStringToOString( seqEquations[ nIndex ],
880 : RTL_TEXTENCODING_ASCII_US ).getStr(), fNumber, 180.0*fNumber/10800000.0);
881 : #endif
882 : }
883 : }
884 0 : catch ( ... )
885 : {
886 : OSL_TRACE("error: EnhancedCustomShape2d::GetEquationValueAsDouble failed");
887 : }
888 : #if OSL_DEBUG_LEVEL > 1
889 : nLevel --;
890 : #endif
891 : }
892 : OSL_TRACE(" ?%d --> %f (angle: %f)", nIndex,
893 : fNumber, 180.0*fNumber/10800000.0);
894 : }
895 :
896 78976 : return fNumber;
897 : }
898 0 : sal_Int32 EnhancedCustomShape2d::GetAdjustValueAsInteger( const sal_Int32 nIndex, const sal_Int32 nDefault ) const
899 : {
900 0 : sal_Int32 nNumber = nDefault;
901 0 : if ( nIndex < seqAdjustmentValues.getLength() )
902 : {
903 0 : if ( seqAdjustmentValues[ nIndex ].Value.getValueTypeClass() == TypeClass_DOUBLE )
904 : {
905 0 : double fNumber = 0;
906 0 : seqAdjustmentValues[ nIndex ].Value >>= fNumber;
907 0 : nNumber = (sal_Int32)fNumber;
908 : }
909 : else
910 0 : seqAdjustmentValues[ nIndex ].Value >>= nNumber;
911 : }
912 0 : return nNumber;
913 : }
914 0 : bool EnhancedCustomShape2d::SetAdjustValueAsDouble( const double& rValue, const sal_Int32 nIndex )
915 : {
916 0 : bool bRetValue = false;
917 0 : if ( nIndex < seqAdjustmentValues.getLength() )
918 : {
919 : // updating our local adjustment sequence
920 0 : seqAdjustmentValues[ nIndex ].Value <<= rValue;
921 0 : seqAdjustmentValues[ nIndex ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
922 0 : bRetValue = true;
923 : }
924 0 : return bRetValue;
925 : }
926 :
927 38128 : Point EnhancedCustomShape2d::GetPoint( const com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPair,
928 : const bool bScale, const bool bReplaceGeoSize ) const
929 : {
930 38128 : Point aRetValue;
931 38128 : bool bExchange = ( nFlags & DFF_CUSTOMSHAPE_EXCH ) != 0; // x <-> y
932 38128 : sal_uInt32 nPass = 0;
933 76256 : do
934 : {
935 76256 : sal_uInt32 nIndex = nPass;
936 :
937 76256 : if ( bExchange )
938 0 : nIndex ^= 1;
939 :
940 : double fVal;
941 76256 : const EnhancedCustomShapeParameter& rParameter = nIndex ? rPair.Second : rPair.First;
942 76256 : if ( nPass ) // height
943 : {
944 38128 : GetParameter( fVal, rParameter, false, bReplaceGeoSize );
945 38128 : fVal -= nCoordTop;
946 38128 : if ( bScale )
947 : {
948 18036 : fVal *= fYScale;
949 :
950 18036 : if ( nFlags & DFF_CUSTOMSHAPE_FLIP_V )
951 0 : fVal = aLogicRect.GetHeight() - fVal;
952 : }
953 38128 : aRetValue.Y() = (sal_Int32)fVal;
954 : }
955 : else // width
956 : {
957 38128 : GetParameter( fVal, rParameter, bReplaceGeoSize, false );
958 38128 : fVal -= nCoordLeft;
959 38128 : if ( bScale )
960 : {
961 18036 : fVal *= fXScale;
962 :
963 18036 : if ( nFlags & DFF_CUSTOMSHAPE_FLIP_H )
964 0 : fVal = aLogicRect.GetWidth() - fVal;
965 : }
966 38128 : aRetValue.X() = static_cast<long>(fVal);
967 : }
968 : }
969 : while ( ++nPass < 2 );
970 38128 : return aRetValue;
971 : }
972 :
973 93944 : bool EnhancedCustomShape2d::GetParameter( double& rRetValue, const EnhancedCustomShapeParameter& rParameter,
974 : const bool bReplaceGeoWidth, const bool bReplaceGeoHeight ) const
975 : {
976 93944 : rRetValue = 0.0;
977 93944 : bool bRetValue = false;
978 93944 : switch ( rParameter.Type )
979 : {
980 : case EnhancedCustomShapeParameterType::ADJUSTMENT :
981 : {
982 8 : sal_Int32 nAdjustmentIndex = 0;
983 8 : if ( rParameter.Value >>= nAdjustmentIndex )
984 : {
985 8 : rRetValue = GetAdjustValueAsDouble( nAdjustmentIndex );
986 8 : bRetValue = true;
987 : }
988 : }
989 8 : break;
990 : case EnhancedCustomShapeParameterType::EQUATION :
991 : {
992 53836 : sal_Int32 nEquationIndex = 0;
993 53836 : if ( rParameter.Value >>= nEquationIndex )
994 : {
995 53836 : rRetValue = GetEquationValueAsDouble( nEquationIndex );
996 53836 : bRetValue = true;
997 : }
998 : }
999 53836 : break;
1000 : case EnhancedCustomShapeParameterType::NORMAL :
1001 : {
1002 40092 : if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE )
1003 : {
1004 0 : double fValue(0.0);
1005 0 : if ( rParameter.Value >>= fValue )
1006 : {
1007 0 : rRetValue = fValue;
1008 0 : bRetValue = true;
1009 : }
1010 : }
1011 : else
1012 : {
1013 40092 : sal_Int32 nValue = 0;
1014 40092 : if ( rParameter.Value >>= nValue )
1015 : {
1016 40092 : rRetValue = nValue;
1017 40092 : bRetValue = true;
1018 40092 : if ( bReplaceGeoWidth && ( nValue == nCoordWidth ) )
1019 9410 : rRetValue *= fXRatio;
1020 30682 : else if ( bReplaceGeoHeight && ( nValue == nCoordHeight ) )
1021 9146 : rRetValue *= fYRatio;
1022 : }
1023 : }
1024 : }
1025 40092 : break;
1026 : case EnhancedCustomShapeParameterType::LEFT :
1027 : {
1028 4 : rRetValue = 0.0;
1029 4 : bRetValue = true;
1030 : }
1031 4 : break;
1032 : case EnhancedCustomShapeParameterType::TOP :
1033 : {
1034 4 : rRetValue = 0.0;
1035 4 : bRetValue = true;
1036 : }
1037 4 : break;
1038 : case EnhancedCustomShapeParameterType::RIGHT :
1039 : {
1040 0 : rRetValue = nCoordWidth;
1041 0 : bRetValue = true;
1042 : }
1043 0 : break;
1044 : case EnhancedCustomShapeParameterType::BOTTOM :
1045 : {
1046 0 : rRetValue = nCoordHeight;
1047 0 : bRetValue = true;
1048 : }
1049 0 : break;
1050 : }
1051 93944 : return bRetValue;
1052 : }
1053 :
1054 : // nLumDat 28-31 = number of luminance entries in nLumDat
1055 : // nLumDat 27-24 = nLumDatEntry 0
1056 : // nLumDat 23-20 = nLumDatEntry 1 ...
1057 : // each 4bit entry is to be interpreted as a 10 percent signed luminance changing
1058 24 : sal_Int32 EnhancedCustomShape2d::GetLuminanceChange( sal_uInt32 nIndex ) const
1059 : {
1060 24 : const sal_uInt32 nCount = nColorData >> 28;
1061 24 : if ( !nCount )
1062 0 : return 0;
1063 :
1064 24 : if ( nIndex >= nCount )
1065 0 : nIndex = nCount - 1;
1066 :
1067 24 : const sal_Int32 nLumDat = nColorData << ( ( 1 + nIndex ) << 2 );
1068 24 : return ( nLumDat >> 28 ) * 10;
1069 : }
1070 :
1071 24 : Color EnhancedCustomShape2d::GetColorData( const Color& rFillColor, sal_uInt32 nIndex, double dBrightness ) const
1072 : {
1073 24 : const sal_Int32 nLuminance = GetLuminanceChange(nIndex);
1074 24 : if( !nLuminance && dBrightness == 1.0 )
1075 12 : return rFillColor;
1076 :
1077 : basegfx::BColor aHSVColor=
1078 : basegfx::tools::rgb2hsv(
1079 12 : basegfx::BColor(rFillColor.GetRed()/255.0,
1080 12 : rFillColor.GetGreen()/255.0,
1081 36 : rFillColor.GetBlue()/255.0));
1082 12 : if (nLuminance ) {
1083 12 : if( nLuminance > 0 )
1084 : {
1085 : aHSVColor.setGreen(
1086 0 : aHSVColor.getGreen() * (1.0-nLuminance/100.0));
1087 : aHSVColor.setBlue(
1088 0 : nLuminance/100.0 +
1089 0 : (1.0-nLuminance/100.0)*aHSVColor.getBlue());
1090 : }
1091 12 : else if( nLuminance < 0 )
1092 : {
1093 : aHSVColor.setBlue(
1094 12 : (1.0+nLuminance/100.0)*aHSVColor.getBlue());
1095 : }
1096 : }
1097 :
1098 12 : aHSVColor = basegfx::tools::hsv2rgb(aHSVColor);
1099 24 : return Color( (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(dBrightness*aHSVColor.getRed(),0.0,1.0) * 255.0 + 0.5 ),
1100 24 : (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(dBrightness*aHSVColor.getGreen(),0.0,1.0) * 255.0 + 0.5 ),
1101 48 : (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(dBrightness*aHSVColor.getBlue(),0.0,1.0) * 255.0 + 0.5 ) );
1102 : }
1103 :
1104 22992 : Rectangle EnhancedCustomShape2d::GetTextRect() const
1105 : {
1106 22992 : sal_Int32 nIndex, nSize = seqTextFrames.getLength();
1107 22992 : if ( !nSize )
1108 12528 : return aLogicRect;
1109 10464 : nIndex = 0;
1110 10464 : if ( bTextFlow && ( nSize > 1 ) )
1111 0 : nIndex++;
1112 10464 : Point aTopLeft( GetPoint( seqTextFrames[ nIndex ].TopLeft, !bOOXMLShape, true ) );
1113 10464 : Point aBottomRight( GetPoint( seqTextFrames[ nIndex ].BottomRight, !bOOXMLShape, true ) );
1114 10464 : if ( bFlipH )
1115 : {
1116 8 : aTopLeft.X() = aLogicRect.GetWidth() - aTopLeft.X();
1117 8 : aBottomRight.X() = aLogicRect.GetWidth() - aBottomRight.X();
1118 : }
1119 10464 : if ( bFlipV )
1120 : {
1121 112 : aTopLeft.Y() = aLogicRect.GetHeight() - aTopLeft.Y();
1122 112 : aBottomRight.Y() = aLogicRect.GetHeight() - aBottomRight.Y();
1123 : }
1124 10464 : Rectangle aRect( aTopLeft, aBottomRight );
1125 : OSL_TRACE("EnhancedCustomShape2d::GetTextRect: %d x %d", aRect.GetWidth(), aRect.GetHeight());
1126 10464 : if( aRect.GetWidth() <= 1 || aRect.GetHeight() <= 1 )
1127 120 : return aLogicRect;
1128 10344 : aRect.Move( aLogicRect.Left(), aLogicRect.Top() );
1129 10344 : aRect.Justify();
1130 10344 : return aRect;
1131 : }
1132 :
1133 2250 : sal_uInt32 EnhancedCustomShape2d::GetHdlCount() const
1134 : {
1135 2250 : return seqHandles.getLength();
1136 : }
1137 :
1138 130 : bool EnhancedCustomShape2d::GetHandlePosition( const sal_uInt32 nIndex, Point& rReturnPosition ) const
1139 : {
1140 130 : bool bRetValue = false;
1141 130 : if ( nIndex < GetHdlCount() )
1142 : {
1143 130 : Handle aHandle;
1144 130 : if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles[ nIndex ], aHandle ) )
1145 : {
1146 130 : if ( aHandle.nFlags & HANDLE_FLAGS_POLAR )
1147 : {
1148 0 : Point aReferencePoint( GetPoint( aHandle.aPolar, true, false ) );
1149 :
1150 : double fAngle;
1151 : double fRadius;
1152 0 : GetParameter( fRadius, aHandle.aPosition.First, false, false );
1153 0 : GetParameter( fAngle, aHandle.aPosition.Second, false, false );
1154 :
1155 0 : double a = ( 360.0 - fAngle ) * F_PI180;
1156 0 : double dx = fRadius * fXScale;
1157 0 : double fX = dx * cos( a );
1158 0 : double fY =-dx * sin( a );
1159 : rReturnPosition =
1160 : Point(
1161 0 : Round( fX + aReferencePoint.X() ),
1162 0 : basegfx::fTools::equalZero(fXScale) ? aReferencePoint.Y() :
1163 0 : Round( ( fY * fYScale ) / fXScale + aReferencePoint.Y() ) );
1164 : }
1165 : else
1166 : {
1167 130 : if ( aHandle.nFlags & HANDLE_FLAGS_SWITCHED )
1168 : {
1169 0 : if ( aLogicRect.GetHeight() > aLogicRect.GetWidth() )
1170 : {
1171 0 : com::sun::star::drawing::EnhancedCustomShapeParameter aFirst = aHandle.aPosition.First;
1172 0 : com::sun::star::drawing::EnhancedCustomShapeParameter aSecond = aHandle.aPosition.Second;
1173 0 : aHandle.aPosition.First = aSecond;
1174 0 : aHandle.aPosition.Second = aFirst;
1175 : }
1176 : }
1177 130 : rReturnPosition = GetPoint( aHandle.aPosition, true, false );
1178 : }
1179 130 : const GeoStat aGeoStat( static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetGeoStat() );
1180 130 : if ( aGeoStat.nShearAngle )
1181 : {
1182 0 : double nTan = aGeoStat.nTan;
1183 0 : if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
1184 0 : nTan = -nTan;
1185 0 : ShearPoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan );
1186 : }
1187 130 : if ( nRotateAngle )
1188 : {
1189 20 : double a = nRotateAngle * F_PI18000;
1190 20 : RotatePoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) );
1191 : }
1192 130 : if ( bFlipH )
1193 2 : rReturnPosition.X() = aLogicRect.GetWidth() - rReturnPosition.X();
1194 130 : if ( bFlipV )
1195 4 : rReturnPosition.Y() = aLogicRect.GetHeight() - rReturnPosition.Y();
1196 130 : rReturnPosition.Move( aLogicRect.Left(), aLogicRect.Top() );
1197 130 : bRetValue = true;
1198 130 : }
1199 : }
1200 130 : return bRetValue;
1201 : }
1202 :
1203 0 : bool EnhancedCustomShape2d::SetHandleControllerPosition( const sal_uInt32 nIndex, const com::sun::star::awt::Point& rPosition )
1204 : {
1205 0 : bool bRetValue = false;
1206 0 : if ( nIndex < GetHdlCount() )
1207 : {
1208 0 : Handle aHandle;
1209 0 : if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles[ nIndex ], aHandle ) )
1210 : {
1211 0 : Point aP( rPosition.X, rPosition.Y );
1212 : // apply the negative object rotation to the controller position
1213 :
1214 0 : aP.Move( -aLogicRect.Left(), -aLogicRect.Top() );
1215 0 : if ( bFlipH )
1216 0 : aP.X() = aLogicRect.GetWidth() - aP.X();
1217 0 : if ( bFlipV )
1218 0 : aP.Y() = aLogicRect.GetHeight() - aP.Y();
1219 0 : if ( nRotateAngle )
1220 : {
1221 0 : double a = -nRotateAngle * F_PI18000;
1222 0 : RotatePoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) );
1223 : }
1224 0 : const GeoStat aGeoStat( static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetGeoStat() );
1225 0 : if ( aGeoStat.nShearAngle )
1226 : {
1227 0 : double nTan = -aGeoStat.nTan;
1228 0 : if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
1229 0 : nTan = -nTan;
1230 0 : ShearPoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan );
1231 : }
1232 :
1233 0 : double fPos1 = aP.X(); //( bFlipH ) ? aLogicRect.GetWidth() - aP.X() : aP.X();
1234 0 : double fPos2 = aP.Y(); //( bFlipV ) ? aLogicRect.GetHeight() -aP.Y() : aP.Y();
1235 0 : fPos1 /= fXScale;
1236 0 : fPos2 /= fYScale;
1237 :
1238 0 : if ( aHandle.nFlags & HANDLE_FLAGS_SWITCHED )
1239 : {
1240 0 : if ( aLogicRect.GetHeight() > aLogicRect.GetWidth() )
1241 : {
1242 0 : double fX = fPos1;
1243 0 : double fY = fPos2;
1244 0 : fPos1 = fY;
1245 0 : fPos2 = fX;
1246 : }
1247 : }
1248 :
1249 0 : sal_Int32 nFirstAdjustmentValue = -1, nSecondAdjustmentValue = -1;
1250 :
1251 0 : if ( aHandle.aPosition.First.Type == EnhancedCustomShapeParameterType::ADJUSTMENT )
1252 0 : aHandle.aPosition.First.Value >>= nFirstAdjustmentValue;
1253 0 : if ( aHandle.aPosition.Second.Type == EnhancedCustomShapeParameterType::ADJUSTMENT )
1254 0 : aHandle.aPosition.Second.Value>>= nSecondAdjustmentValue;
1255 :
1256 0 : if ( aHandle.nFlags & HANDLE_FLAGS_POLAR )
1257 : {
1258 : double fXRef, fYRef, fAngle;
1259 0 : GetParameter( fXRef, aHandle.aPolar.First, false, false );
1260 0 : GetParameter( fYRef, aHandle.aPolar.Second, false, false );
1261 0 : const double fDX = fPos1 - fXRef;
1262 0 : fAngle = -( atan2( -fPos2 + fYRef, ( ( fDX == 0.0L ) ? 0.000000001 : fDX ) ) / F_PI180 );
1263 0 : double fX = ( fPos1 - fXRef );
1264 0 : double fY = ( fPos2 - fYRef );
1265 0 : double fRadius = sqrt( fX * fX + fY * fY );
1266 0 : if ( aHandle.nFlags & HANDLE_FLAGS_RADIUS_RANGE_MINIMUM )
1267 : {
1268 : double fMin;
1269 0 : GetParameter( fMin, aHandle.aRadiusRangeMinimum, false, false );
1270 0 : if ( fRadius < fMin )
1271 0 : fRadius = fMin;
1272 : }
1273 0 : if ( aHandle.nFlags & HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM )
1274 : {
1275 : double fMax;
1276 0 : GetParameter( fMax, aHandle.aRadiusRangeMaximum, false, false );
1277 0 : if ( fRadius > fMax )
1278 0 : fRadius = fMax;
1279 : }
1280 0 : if ( nFirstAdjustmentValue >= 0 )
1281 0 : SetAdjustValueAsDouble( fRadius, nFirstAdjustmentValue );
1282 0 : if ( nSecondAdjustmentValue >= 0 )
1283 0 : SetAdjustValueAsDouble( fAngle, nSecondAdjustmentValue );
1284 : }
1285 : else
1286 : {
1287 0 : if ( aHandle.nFlags & HANDLE_FLAGS_REFX )
1288 : {
1289 0 : nFirstAdjustmentValue = aHandle.nRefX;
1290 0 : fPos1 *= 100000.0;
1291 0 : fPos1 /= nCoordWidth;
1292 : }
1293 0 : if ( aHandle.nFlags & HANDLE_FLAGS_REFY )
1294 : {
1295 0 : nSecondAdjustmentValue = aHandle.nRefY;
1296 0 : fPos2 *= 100000.0;
1297 0 : fPos2 /= nCoordHeight;
1298 : }
1299 0 : if ( nFirstAdjustmentValue >= 0 )
1300 : {
1301 0 : if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_X_MINIMUM ) // check if horizontal handle needs to be within a range
1302 : {
1303 : double fXMin;
1304 0 : GetParameter( fXMin, aHandle.aXRangeMinimum, false, false );
1305 0 : if ( fPos1 < fXMin )
1306 0 : fPos1 = fXMin;
1307 : }
1308 0 : if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_X_MAXIMUM ) // check if horizontal handle needs to be within a range
1309 : {
1310 : double fXMax;
1311 0 : GetParameter( fXMax, aHandle.aXRangeMaximum, false, false );
1312 0 : if ( fPos1 > fXMax )
1313 0 : fPos1 = fXMax;
1314 : }
1315 0 : SetAdjustValueAsDouble( fPos1, nFirstAdjustmentValue );
1316 : }
1317 0 : if ( nSecondAdjustmentValue >= 0 )
1318 : {
1319 0 : if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_Y_MINIMUM ) // check if vertical handle needs to be within a range
1320 : {
1321 : double fYMin;
1322 0 : GetParameter( fYMin, aHandle.aYRangeMinimum, false, false );
1323 0 : if ( fPos2 < fYMin )
1324 0 : fPos2 = fYMin;
1325 : }
1326 0 : if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_Y_MAXIMUM ) // check if vertical handle needs to be within a range
1327 : {
1328 : double fYMax;
1329 0 : GetParameter( fYMax, aHandle.aYRangeMaximum, false, false );
1330 0 : if ( fPos2 > fYMax )
1331 0 : fPos2 = fYMax;
1332 : }
1333 0 : SetAdjustValueAsDouble( fPos2, nSecondAdjustmentValue );
1334 : }
1335 : }
1336 : // and writing them back into the GeometryItem
1337 : SdrCustomShapeGeometryItem aGeometryItem(
1338 0 : static_cast<const SdrCustomShapeGeometryItem&>(pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )));
1339 0 : com::sun::star::beans::PropertyValue aPropVal;
1340 0 : aPropVal.Name = "AdjustmentValues";
1341 0 : aPropVal.Value <<= seqAdjustmentValues;
1342 0 : aGeometryItem.SetPropertyValue( aPropVal );
1343 0 : pCustomShapeObj->SetMergedItem( aGeometryItem );
1344 0 : bRetValue = true;
1345 0 : }
1346 : }
1347 0 : return bRetValue;
1348 : }
1349 :
1350 0 : void EnhancedCustomShape2d::SwapStartAndEndArrow( SdrObject* pObj ) //#108274
1351 : {
1352 0 : XLineStartItem aLineStart;
1353 0 : aLineStart.SetLineStartValue(static_cast<const XLineStartItem&>(pObj->GetMergedItem( XATTR_LINEEND )).GetLineStartValue());
1354 0 : XLineStartWidthItem aLineStartWidth(static_cast<const XLineStartWidthItem&>(pObj->GetMergedItem( XATTR_LINEENDWIDTH )).GetValue());
1355 0 : XLineStartCenterItem aLineStartCenter(static_cast<const XLineStartCenterItem&>(pObj->GetMergedItem( XATTR_LINEENDCENTER )).GetValue());
1356 :
1357 0 : XLineEndItem aLineEnd;
1358 0 : aLineEnd.SetLineEndValue(static_cast<const XLineEndItem&>(pObj->GetMergedItem( XATTR_LINESTART )).GetLineEndValue());
1359 0 : XLineEndWidthItem aLineEndWidth(static_cast<const XLineEndWidthItem&>(pObj->GetMergedItem( XATTR_LINESTARTWIDTH )).GetValue());
1360 0 : XLineEndCenterItem aLineEndCenter(static_cast<const XLineEndCenterItem&>(pObj->GetMergedItem( XATTR_LINESTARTCENTER )).GetValue());
1361 :
1362 0 : pObj->SetMergedItem( aLineStart );
1363 0 : pObj->SetMergedItem( aLineStartWidth );
1364 0 : pObj->SetMergedItem( aLineStartCenter );
1365 0 : pObj->SetMergedItem( aLineEnd );
1366 0 : pObj->SetMergedItem( aLineEndWidth );
1367 0 : pObj->SetMergedItem( aLineEndCenter );
1368 0 : }
1369 :
1370 4526 : static basegfx::B2DPolygon CreateArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, const bool bClockwise, bool bFullCircle = false )
1371 : {
1372 4526 : Rectangle aRect( rRect );
1373 4526 : Point aStart( rStart );
1374 4526 : Point aEnd( rEnd );
1375 :
1376 4526 : sal_Int32 bSwapStartEndAngle = 0;
1377 :
1378 4526 : if ( aRect.Left() > aRect.Right() )
1379 0 : bSwapStartEndAngle ^= 0x01;
1380 4526 : if ( aRect.Top() > aRect.Bottom() )
1381 0 : bSwapStartEndAngle ^= 0x11;
1382 4526 : if ( bSwapStartEndAngle )
1383 : {
1384 0 : aRect.Justify();
1385 0 : if ( bSwapStartEndAngle & 1 )
1386 : {
1387 0 : Point aTmp( aStart );
1388 0 : aStart = aEnd;
1389 0 : aEnd = aTmp;
1390 : }
1391 : }
1392 :
1393 4526 : Polygon aTempPoly( aRect, aStart, aEnd, POLY_ARC, bFullCircle );
1394 4526 : basegfx::B2DPolygon aRetval;
1395 :
1396 4526 : if ( bClockwise )
1397 : {
1398 156440 : for ( sal_uInt16 j = aTempPoly.GetSize(); j--; )
1399 : {
1400 147516 : aRetval.append(basegfx::B2DPoint(aTempPoly[ j ].X(), aTempPoly[ j ].Y()));
1401 : }
1402 : }
1403 : else
1404 : {
1405 2068 : for ( sal_uInt16 j = 0; j < aTempPoly.GetSize(); j++ )
1406 : {
1407 2004 : aRetval.append(basegfx::B2DPoint(aTempPoly[ j ].X(), aTempPoly[ j ].Y()));
1408 : }
1409 : }
1410 :
1411 4526 : return aRetval;
1412 : }
1413 :
1414 3066 : void EnhancedCustomShape2d::CreateSubPath( sal_uInt16& rSrcPt, sal_uInt16& rSegmentInd, std::vector< SdrPathObj* >& rObjectList,
1415 : const bool bLineGeometryNeededOnly,
1416 : const bool bSortFilledObjectsToBack,
1417 : sal_Int32 nIndex )
1418 : {
1419 3066 : bool bNoFill = false;
1420 3066 : bool bNoStroke = false;
1421 3066 : double dBrightness = 1.0;
1422 :
1423 3066 : basegfx::B2DPolyPolygon aNewB2DPolyPolygon;
1424 6132 : basegfx::B2DPolygon aNewB2DPolygon;
1425 :
1426 3066 : SetPathSize( nIndex );
1427 :
1428 3066 : sal_Int32 nCoordSize = seqCoordinates.getLength();
1429 3066 : sal_Int32 nSegInfoSize = seqSegments.getLength();
1430 3066 : if ( !nSegInfoSize )
1431 : {
1432 60 : const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
1433 :
1434 584 : for ( sal_Int32 nPtNum(0L); nPtNum < nCoordSize; nPtNum++ )
1435 : {
1436 524 : const Point aTempPoint(GetPoint( *pTmp++, true, true ));
1437 524 : aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
1438 : }
1439 :
1440 60 : aNewB2DPolygon.setClosed(true);
1441 : }
1442 : else
1443 : {
1444 19014 : for ( ;rSegmentInd < nSegInfoSize; )
1445 : {
1446 16008 : sal_Int16 nCommand = seqSegments[ rSegmentInd ].Command;
1447 16008 : sal_Int16 nPntCount= seqSegments[ rSegmentInd++ ].Count;
1448 :
1449 16008 : switch ( nCommand )
1450 : {
1451 : case NOFILL :
1452 68 : bNoFill = true;
1453 68 : break;
1454 : case NOSTROKE :
1455 12 : bNoStroke = true;
1456 12 : break;
1457 : case DARKEN :
1458 0 : dBrightness = 0.66666666;
1459 0 : break;
1460 : case DARKENLESS :
1461 0 : dBrightness = 0.83333333;
1462 0 : break;
1463 : case LIGHTEN :
1464 0 : dBrightness = 1.16666666;
1465 0 : break;
1466 : case LIGHTENLESS :
1467 0 : dBrightness = 1.33333333;
1468 0 : break;
1469 : case MOVETO :
1470 : {
1471 3054 : if(aNewB2DPolygon.count() > 1L)
1472 : {
1473 : // #i76201# Add conversion to closed polygon when first and last points are equal
1474 86 : basegfx::tools::checkClosed(aNewB2DPolygon);
1475 86 : aNewB2DPolyPolygon.append(aNewB2DPolygon);
1476 : }
1477 :
1478 3054 : aNewB2DPolygon.clear();
1479 :
1480 3054 : if ( rSrcPt < nCoordSize )
1481 : {
1482 3054 : const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
1483 : OSL_TRACE("moveTo: %d,%d", aTempPoint.X(), aTempPoint.Y());
1484 3054 : aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
1485 : }
1486 : }
1487 3054 : break;
1488 : case ENDSUBPATH :
1489 3006 : break;
1490 : case CLOSESUBPATH :
1491 : {
1492 1444 : if(aNewB2DPolygon.count())
1493 : {
1494 1444 : if(aNewB2DPolygon.count() > 1L)
1495 : {
1496 1444 : aNewB2DPolygon.setClosed(true);
1497 1444 : aNewB2DPolyPolygon.append(aNewB2DPolygon);
1498 : }
1499 :
1500 1444 : aNewB2DPolygon.clear();
1501 : }
1502 : }
1503 1444 : break;
1504 : case CURVETO :
1505 : {
1506 1780 : for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ )
1507 : {
1508 1018 : const Point aControlA(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
1509 1018 : const Point aControlB(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
1510 1018 : const Point aEnd(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
1511 :
1512 : DBG_ASSERT(aNewB2DPolygon.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding control point (!)");
1513 : aNewB2DPolygon.appendBezierSegment(
1514 2036 : basegfx::B2DPoint(aControlA.X(), aControlA.Y()),
1515 2036 : basegfx::B2DPoint(aControlB.X(), aControlB.Y()),
1516 5090 : basegfx::B2DPoint(aEnd.X(), aEnd.Y()));
1517 : }
1518 : }
1519 762 : break;
1520 :
1521 : case ANGLEELLIPSE :
1522 : {
1523 6 : if ( nPntCount )
1524 : {
1525 6 : if(aNewB2DPolygon.count() > 1L)
1526 : {
1527 : // #i76201# Add conversion to closed polygon when first and last points are equal
1528 0 : basegfx::tools::checkClosed(aNewB2DPolygon);
1529 0 : aNewB2DPolyPolygon.append(aNewB2DPolygon);
1530 : }
1531 6 : aNewB2DPolygon.clear();
1532 : }
1533 : }
1534 : case ANGLEELLIPSETO :
1535 : {
1536 12 : for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ )
1537 : {
1538 : // create a circle
1539 6 : Point _aCenter;
1540 : double fWidth, fHeight;
1541 6 : const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( mso_sptEllipse );
1542 6 : bool bIsDefaultViewBox = false;
1543 6 : bool bIsDefaultPath = false;
1544 6 : bool bIsMSEllipse = false;
1545 :
1546 6 : if( ( nCoordWidth == pDefCustomShape->nCoordWidth )
1547 6 : && ( nCoordHeight == pDefCustomShape->nCoordHeight ) )
1548 6 : bIsDefaultViewBox = true;
1549 6 : sal_Int32 j, nCount = pDefCustomShape->nVertices;//==3
1550 12 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2;
1551 :
1552 6 : seqCoordinates1.realloc( nCount );
1553 24 : for ( j = 0; j < nCount; j++ )
1554 : {
1555 18 : seqCoordinates1[j] = seqCoordinates[ rSrcPt + j];
1556 : }
1557 :
1558 6 : seqCoordinates2.realloc( nCount );
1559 24 : for ( j = 0; j < nCount; j++ )
1560 : {
1561 18 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ j ].First, pDefCustomShape->pVertices[ j ].nValA );
1562 18 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ j ].Second, pDefCustomShape->pVertices[ j ].nValB );
1563 : }
1564 6 : if(seqCoordinates1 == seqCoordinates2)
1565 6 : bIsDefaultPath = true;
1566 :
1567 12 : OUString sShpType;
1568 6 : SdrCustomShapeGeometryItem& rGeometryItem = const_cast<SdrCustomShapeGeometryItem&>(static_cast<const SdrCustomShapeGeometryItem&>(pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )));
1569 6 : Any* pAny = rGeometryItem.GetPropertyValueByName( "Type" );
1570 6 : if ( pAny )
1571 6 : *pAny >>= sShpType;
1572 12 : if( sShpType.getLength() > 3 &&
1573 6 : sShpType.startsWith( "mso" )){
1574 0 : bIsMSEllipse = true;
1575 : }
1576 6 : if( (! bIsDefaultPath && ! bIsDefaultViewBox) || (bIsDefaultViewBox && bIsMSEllipse) /*&& (nGeneratorVersion == SfxObjectShell::Sym_L2)*/ )
1577 : {
1578 0 : _aCenter = GetPoint( seqCoordinates[ rSrcPt ], true, true );
1579 0 : GetParameter( fWidth, seqCoordinates[ rSrcPt + 1 ].First, true, false );
1580 0 : GetParameter( fHeight, seqCoordinates[ rSrcPt + 1 ].Second, false, true );
1581 0 : fWidth /= 2;
1582 0 : fHeight /= 2;
1583 6 : }else if( bIsDefaultPath && !bIsDefaultViewBox /*&& (nGeneratorVersion == SfxObjectShell::Sym_L2)*/ )
1584 : {
1585 0 : _aCenter.X() = nCoordWidth/2 * fXScale;
1586 0 : _aCenter.Y() = nCoordHeight/2 * fYScale;
1587 0 : fWidth = nCoordWidth/2;
1588 0 : fHeight = nCoordHeight/2;
1589 0 : const Any* pViewBox = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( "ViewBox" );
1590 0 : com::sun::star::awt::Rectangle aViewBox;
1591 0 : if ( pViewBox && (*pViewBox >>= aViewBox ) )
1592 : {
1593 0 : aViewBox.Width = pDefCustomShape->nCoordWidth;
1594 0 : aViewBox.Height = pDefCustomShape->nCoordHeight;
1595 : }
1596 0 : com::sun::star::beans::PropertyValue aPropVal;
1597 0 : aPropVal.Name = "ViewBox";
1598 0 : aPropVal.Value <<= aViewBox;
1599 0 : rGeometryItem.SetPropertyValue( aPropVal );
1600 0 : pCustomShapeObj->SetMergedItem( rGeometryItem );
1601 : }else{
1602 6 : _aCenter = GetPoint( seqCoordinates[ rSrcPt ], true, true );
1603 6 : GetParameter( fWidth, seqCoordinates[ rSrcPt + 1 ].First, true, false);
1604 6 : GetParameter( fHeight, seqCoordinates[ rSrcPt + 1 ].Second, false, true );
1605 : }
1606 :
1607 6 : fWidth *= fXScale;
1608 6 : fHeight*= fYScale;
1609 6 : Point aP( (sal_Int32)( _aCenter.X() - fWidth ), (sal_Int32)( _aCenter.Y() - fHeight ) );
1610 6 : Size aS( (sal_Int32)( fWidth * 2.0 ), (sal_Int32)( fHeight * 2.0 ) );
1611 6 : Rectangle aRect( aP, aS );
1612 6 : if ( aRect.GetWidth() && aRect.GetHeight() )
1613 : {
1614 : double fStartAngle, fEndAngle;
1615 6 : GetParameter( fStartAngle, seqCoordinates[ rSrcPt + 2 ].First, false, false );
1616 6 : GetParameter( fEndAngle , seqCoordinates[ rSrcPt + 2 ].Second, false, false );
1617 :
1618 6 : if ( ((sal_Int32)fStartAngle % 360) != ((sal_Int32)fEndAngle % 360) )
1619 : {
1620 0 : if ( (sal_Int32)fStartAngle & 0x7fff0000 ) // SJ: if the angle was imported from our escher import, then the
1621 0 : fStartAngle /= 65536.0; // value is shifted by 16. TODO: already change the fixed float to a
1622 0 : if ( (sal_Int32)fEndAngle & 0x7fff0000 ) // double in the import filter
1623 : {
1624 0 : fEndAngle /= 65536.0;
1625 0 : fEndAngle = fEndAngle + fStartAngle;
1626 0 : if ( fEndAngle < 0 )
1627 : { // in the binary filter the endangle is the amount
1628 0 : double fTemp = fStartAngle;
1629 0 : fStartAngle = fEndAngle;
1630 0 : fEndAngle = fTemp;
1631 : }
1632 : }
1633 0 : double fCenterX = aRect.Center().X();
1634 0 : double fCenterY = aRect.Center().Y();
1635 0 : double fx1 = ( cos( fStartAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX;
1636 0 : double fy1 = ( -sin( fStartAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY;
1637 0 : double fx2 = ( cos( fEndAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX;
1638 0 : double fy2 = ( -sin( fEndAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY;
1639 0 : aNewB2DPolygon.append(CreateArc( aRect, Point( (sal_Int32)fx1, (sal_Int32)fy1 ), Point( (sal_Int32)fx2, (sal_Int32)fy2 ), false));
1640 : }
1641 : else
1642 : { /* SJ: TODO: this block should be replaced sometimes, because the current point
1643 : is not set correct, it also does not use the correct moveto
1644 : point if ANGLEELLIPSETO was used, but the method CreateArc
1645 : is at the moment not able to draw full circles (if startangle is 0
1646 : and endangle 360 nothing is painted :-( */
1647 6 : sal_Int32 nXControl = (sal_Int32)((double)aRect.GetWidth() * 0.2835 );
1648 6 : sal_Int32 nYControl = (sal_Int32)((double)aRect.GetHeight() * 0.2835 );
1649 6 : Point aCenter( aRect.Center() );
1650 :
1651 : // append start point
1652 6 : aNewB2DPolygon.append(basegfx::B2DPoint(aCenter.X(), aRect.Top()));
1653 :
1654 : // append four bezier segments
1655 : aNewB2DPolygon.appendBezierSegment(
1656 12 : basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Top()),
1657 12 : basegfx::B2DPoint(aRect.Right(), aCenter.Y() - nYControl),
1658 30 : basegfx::B2DPoint(aRect.Right(), aCenter.Y()));
1659 :
1660 : aNewB2DPolygon.appendBezierSegment(
1661 12 : basegfx::B2DPoint(aRect.Right(), aCenter.Y() + nYControl),
1662 12 : basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Bottom()),
1663 30 : basegfx::B2DPoint(aCenter.X(), aRect.Bottom()));
1664 :
1665 : aNewB2DPolygon.appendBezierSegment(
1666 12 : basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Bottom()),
1667 12 : basegfx::B2DPoint(aRect.Left(), aCenter.Y() + nYControl),
1668 30 : basegfx::B2DPoint(aRect.Left(), aCenter.Y()));
1669 :
1670 : aNewB2DPolygon.appendBezierSegment(
1671 12 : basegfx::B2DPoint(aRect.Left(), aCenter.Y() - nYControl),
1672 12 : basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Top()),
1673 30 : basegfx::B2DPoint(aCenter.X(), aRect.Top()));
1674 :
1675 : // close, rescue last controlpoint, remove double last point
1676 6 : basegfx::tools::closeWithGeometryChange(aNewB2DPolygon);
1677 : }
1678 : }
1679 6 : rSrcPt += 3;
1680 6 : }
1681 : }
1682 6 : break;
1683 :
1684 : case QUADRATICCURVETO :
1685 : {
1686 0 : for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt + 1 < nCoordSize ); i++ )
1687 : {
1688 0 : if ( rSrcPt )
1689 : {
1690 0 : const Point aPreviousEndPoint(GetPoint( seqCoordinates[ rSrcPt - 1 ], true, true));
1691 0 : const Point aControlQ(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
1692 0 : const Point aEnd(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
1693 0 : const Point aControlA((aPreviousEndPoint + (aControlQ * 2)) / 3);
1694 0 : const Point aControlB(((aControlQ * 2) + aEnd) / 3);
1695 :
1696 : DBG_ASSERT(aNewB2DPolygon.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding Q control point (!)");
1697 : aNewB2DPolygon.appendBezierSegment(
1698 0 : basegfx::B2DPoint(aControlA.X(), aControlA.Y()),
1699 0 : basegfx::B2DPoint(aControlB.X(), aControlB.Y()),
1700 0 : basegfx::B2DPoint(aEnd.X(), aEnd.Y()));
1701 : }
1702 : else // no previous point , do a moveto
1703 : {
1704 0 : rSrcPt++; // skip control point
1705 0 : const Point aEnd(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
1706 :
1707 : DBG_ASSERT(aNewB2DPolygon.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding Q control point (!)");
1708 0 : aNewB2DPolygon.append(basegfx::B2DPoint(aEnd.X(), aEnd.Y()));
1709 : }
1710 : }
1711 : }
1712 0 : break;
1713 :
1714 : case LINETO :
1715 : {
1716 14200 : for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ )
1717 : {
1718 9832 : const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], true, true ));
1719 : OSL_TRACE("lineTo: %d,%d", aTempPoint.X(), aTempPoint.Y());
1720 9832 : aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y()));
1721 : }
1722 : }
1723 4368 : break;
1724 :
1725 : case ARC :
1726 : case CLOCKWISEARC :
1727 : {
1728 24 : if(aNewB2DPolygon.count() > 1L)
1729 : {
1730 : // #i76201# Add conversion to closed polygon when first and last points are equal
1731 0 : basegfx::tools::checkClosed(aNewB2DPolygon);
1732 0 : aNewB2DPolyPolygon.append(aNewB2DPolygon);
1733 : }
1734 :
1735 24 : aNewB2DPolygon.clear();
1736 : }
1737 : case ARCTO :
1738 : case CLOCKWISEARCTO :
1739 : {
1740 86 : bool bClockwise = ( nCommand == CLOCKWISEARC ) || ( nCommand == CLOCKWISEARCTO );
1741 86 : sal_uInt32 nXor = bClockwise ? 3 : 2;
1742 196 : for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 3 ) < nCoordSize ); i++ )
1743 : {
1744 110 : Rectangle aRect( GetPoint( seqCoordinates[ rSrcPt ], true, true ), GetPoint( seqCoordinates[ rSrcPt + 1 ], true, true ) );
1745 110 : if ( aRect.GetWidth() && aRect.GetHeight() )
1746 : {
1747 110 : Point aCenter( aRect.Center() );
1748 110 : Point aStart( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + nXor ) ], true, true ) );
1749 110 : Point aEnd( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + ( nXor ^ 1 ) ) ], true, true ) );
1750 110 : aStart.X() = (sal_Int32)( ( (double)( aStart.X() - aCenter.X() ) ) ) + aCenter.X();
1751 110 : aStart.Y() = (sal_Int32)( ( (double)( aStart.Y() - aCenter.Y() ) ) ) + aCenter.Y();
1752 110 : aEnd.X() = (sal_Int32)( ( (double)( aEnd.X() - aCenter.X() ) ) ) + aCenter.X();
1753 110 : aEnd.Y() = (sal_Int32)( ( (double)( aEnd.Y() - aCenter.Y() ) ) ) + aCenter.Y();
1754 110 : aNewB2DPolygon.append(CreateArc( aRect, aStart, aEnd, bClockwise));
1755 : }
1756 110 : rSrcPt += 4;
1757 : }
1758 : }
1759 86 : break;
1760 :
1761 : case ARCANGLETO :
1762 : {
1763 : double fWR, fHR, fStartAngle, fSwingAngle;
1764 :
1765 7618 : for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( rSrcPt + 1 < nCoordSize ); i++ )
1766 : {
1767 4416 : GetParameter ( fWR, seqCoordinates[ (sal_uInt16)( rSrcPt ) ].First, true, false );
1768 4416 : GetParameter ( fHR, seqCoordinates[ (sal_uInt16)( rSrcPt ) ].Second, false, true );
1769 :
1770 4416 : GetParameter ( fStartAngle, seqCoordinates[ (sal_uInt16)( rSrcPt + 1) ].First, false, false );
1771 4416 : GetParameter ( fSwingAngle, seqCoordinates[ (sal_uInt16)( rSrcPt + 1 ) ].Second, false, false );
1772 :
1773 4416 : fWR *= fXScale;
1774 4416 : fHR *= fYScale;
1775 :
1776 4416 : fStartAngle *= F_PI180;
1777 4416 : fSwingAngle *= F_PI180;
1778 :
1779 : OSL_TRACE("ARCANGLETO scale: %f x %f angles: %f, %f", fWR, fHR, fStartAngle, fSwingAngle);
1780 :
1781 4416 : bool bClockwise = fSwingAngle >= 0.0;
1782 :
1783 4416 : if (aNewB2DPolygon.count() > 0)
1784 : {
1785 4416 : basegfx::B2DPoint aStartPointB2D( aNewB2DPolygon.getB2DPoint(aNewB2DPolygon.count() - 1 ) );
1786 4416 : Point aStartPoint( aStartPointB2D.getX(), aStartPointB2D.getY() );
1787 :
1788 4416 : double fT = atan2((fWR*sin(fStartAngle)), (fHR*cos(fStartAngle)));
1789 4416 : double fTE = atan2((fWR*sin(fStartAngle + fSwingAngle)), fHR*cos(fStartAngle + fSwingAngle));
1790 :
1791 : OSL_TRACE("ARCANGLETO angles: %f, %f --> parameters: %f, %f", fStartAngle, fSwingAngle, fT, fTE );
1792 :
1793 8832 : Rectangle aRect ( Point ( aStartPoint.getX() - fWR*cos(fT) - fWR, aStartPoint.getY() - fHR*sin(fT) - fHR ),
1794 13248 : Point ( aStartPoint.getX() - fWR*cos(fT) + fWR, aStartPoint.getY() - fHR*sin(fT) + fHR) );
1795 :
1796 4416 : Point aEndPoint ( aStartPoint.getX() - fWR*(cos(fT) - cos(fTE)), aStartPoint.getY() - fHR*(sin(fT) - sin(fTE)) );
1797 :
1798 : OSL_TRACE("ARCANGLETO rect: %d, %d x %d, %d start: %d, %d end: %d, %d clockwise: %d",
1799 : aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom(),
1800 : aStartPoint.X(), aStartPoint.Y(), aEndPoint.X(), aEndPoint.Y(), bClockwise);
1801 4416 : aNewB2DPolygon.append(CreateArc( aRect, bClockwise ? aEndPoint : aStartPoint, bClockwise ? aStartPoint : aEndPoint, bClockwise, aStartPoint == aEndPoint && fSwingAngle > F_PI));
1802 : }
1803 :
1804 4416 : rSrcPt += 2;
1805 : }
1806 : }
1807 3202 : break;
1808 :
1809 : case ELLIPTICALQUADRANTX :
1810 : case ELLIPTICALQUADRANTY :
1811 : {
1812 0 : bool bFirstDirection(true);
1813 0 : basegfx::B2DPoint aControlPointA;
1814 0 : basegfx::B2DPoint aControlPointB;
1815 :
1816 0 : for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ )
1817 : {
1818 0 : sal_uInt32 nModT = ( nCommand == ELLIPTICALQUADRANTX ) ? 1 : 0;
1819 0 : Point aCurrent( GetPoint( seqCoordinates[ rSrcPt ], true, true ) );
1820 :
1821 0 : if ( rSrcPt ) // we need a previous point
1822 : {
1823 0 : Point aPrev( GetPoint( seqCoordinates[ rSrcPt - 1 ], true, true ) );
1824 : sal_Int32 nX, nY;
1825 0 : nX = aCurrent.X() - aPrev.X();
1826 0 : nY = aCurrent.Y() - aPrev.Y();
1827 0 : if ( ( nY ^ nX ) & 0x80000000 )
1828 : {
1829 0 : if ( !i )
1830 0 : bFirstDirection = true;
1831 0 : else if ( !bFirstDirection )
1832 0 : nModT ^= 1;
1833 : }
1834 : else
1835 : {
1836 0 : if ( !i )
1837 0 : bFirstDirection = false;
1838 0 : else if ( bFirstDirection )
1839 0 : nModT ^= 1;
1840 : }
1841 0 : if ( nModT ) // get the right corner
1842 : {
1843 0 : nX = aCurrent.X();
1844 0 : nY = aPrev.Y();
1845 : }
1846 : else
1847 : {
1848 0 : nX = aPrev.X();
1849 0 : nY = aCurrent.Y();
1850 : }
1851 0 : sal_Int32 nXVec = ( nX - aPrev.X() ) >> 1;
1852 0 : sal_Int32 nYVec = ( nY - aPrev.Y() ) >> 1;
1853 0 : Point aControl1( aPrev.X() + nXVec, aPrev.Y() + nYVec );
1854 :
1855 0 : aControlPointA = basegfx::B2DPoint(aControl1.X(), aControl1.Y());
1856 :
1857 0 : nXVec = ( nX - aCurrent.X() ) >> 1;
1858 0 : nYVec = ( nY - aCurrent.Y() ) >> 1;
1859 0 : Point aControl2( aCurrent.X() + nXVec, aCurrent.Y() + nYVec );
1860 :
1861 0 : aControlPointB = basegfx::B2DPoint(aControl2.X(), aControl2.Y());
1862 :
1863 : aNewB2DPolygon.appendBezierSegment(
1864 : aControlPointA,
1865 : aControlPointB,
1866 0 : basegfx::B2DPoint(aCurrent.X(), aCurrent.Y()));
1867 : }
1868 : else
1869 : {
1870 0 : aNewB2DPolygon.append(basegfx::B2DPoint(aCurrent.X(), aCurrent.Y()));
1871 : }
1872 :
1873 0 : rSrcPt++;
1874 0 : }
1875 : }
1876 0 : break;
1877 :
1878 : #ifdef DBG_CUSTOMSHAPE
1879 : case UNKNOWN :
1880 : default :
1881 : {
1882 : OStringBuffer aString("CustomShapes::unknown PolyFlagValue :");
1883 : aString.append(static_cast<sal_Int32>(nCommand));
1884 : OSL_FAIL(aString.getStr());
1885 : }
1886 : break;
1887 : #endif
1888 : }
1889 16008 : if ( nCommand == ENDSUBPATH )
1890 3006 : break;
1891 : }
1892 : }
1893 3066 : if ( rSegmentInd == nSegInfoSize )
1894 2766 : rSegmentInd++;
1895 :
1896 3066 : if(aNewB2DPolygon.count() > 1L)
1897 : {
1898 : // #i76201# Add conversion to closed polygon when first and last points are equal
1899 1640 : basegfx::tools::checkClosed(aNewB2DPolygon);
1900 1640 : aNewB2DPolyPolygon.append(aNewB2DPolygon);
1901 : }
1902 :
1903 3066 : if(aNewB2DPolyPolygon.count())
1904 : {
1905 3066 : if( !bLineGeometryNeededOnly )
1906 : {
1907 : // hack aNewB2DPolyPolygon to fill logic rect - this is
1908 : // needed to produce gradient fills that look like mso
1909 2848 : aNewB2DPolygon.clear();
1910 2848 : aNewB2DPolygon.append(basegfx::B2DPoint(0,0));
1911 2848 : aNewB2DPolygon.setClosed(true);
1912 2848 : aNewB2DPolyPolygon.append(aNewB2DPolygon);
1913 :
1914 2848 : aNewB2DPolygon.clear();
1915 2848 : aNewB2DPolygon.append(basegfx::B2DPoint(aLogicRect.GetWidth(),
1916 5696 : aLogicRect.GetHeight()));
1917 2848 : aNewB2DPolygon.setClosed(true);
1918 2848 : aNewB2DPolyPolygon.append(aNewB2DPolygon);
1919 : }
1920 :
1921 : // #i37011#
1922 3066 : bool bForceCreateTwoObjects(false);
1923 :
1924 3066 : if(!bSortFilledObjectsToBack && !aNewB2DPolyPolygon.isClosed() && !bNoStroke)
1925 : {
1926 912 : bForceCreateTwoObjects = true;
1927 : }
1928 :
1929 3066 : if(bLineGeometryNeededOnly)
1930 : {
1931 218 : bForceCreateTwoObjects = true;
1932 218 : bNoFill = true;
1933 218 : bNoStroke = false;
1934 : }
1935 :
1936 3066 : if(bForceCreateTwoObjects || bSortFilledObjectsToBack)
1937 : {
1938 2952 : if(bFilled && !bNoFill)
1939 : {
1940 1878 : basegfx::B2DPolyPolygon aClosedPolyPolygon(aNewB2DPolyPolygon);
1941 1878 : aClosedPolyPolygon.setClosed(true);
1942 1878 : SdrPathObj* pFill = new SdrPathObj(OBJ_POLY, aClosedPolyPolygon, dBrightness);
1943 3756 : SfxItemSet aTempSet(*this);
1944 1878 : aTempSet.Put(makeSdrShadowItem(false));
1945 1878 : aTempSet.Put(XLineStyleItem(XLINE_NONE));
1946 1878 : pFill->SetMergedItemSet(aTempSet);
1947 3756 : rObjectList.push_back(pFill);
1948 : }
1949 :
1950 2952 : if(!bNoStroke)
1951 : {
1952 : // there is no reason to use OBJ_PLIN here when the polygon is actually closed,
1953 : // the non-fill is defined by XFILL_NONE. Since SdrPathObj::ImpForceKind() needs
1954 : // to correct the polygon (here: open it) using the type, the last edge may get lost.
1955 : // Thus, use a type that fits the polygon
1956 : SdrPathObj* pStroke = new SdrPathObj(
1957 2940 : aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN,
1958 2940 : aNewB2DPolyPolygon, dBrightness);
1959 2940 : SfxItemSet aTempSet(*this);
1960 2940 : aTempSet.Put(makeSdrShadowItem(false));
1961 2940 : aTempSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
1962 2940 : pStroke->SetMergedItemSet(aTempSet);
1963 2940 : rObjectList.push_back(pStroke);
1964 2952 : }
1965 : }
1966 : else
1967 : {
1968 114 : SdrPathObj* pObj = 0;
1969 114 : SfxItemSet aTempSet(*this);
1970 114 : aTempSet.Put(makeSdrShadowItem(false));
1971 :
1972 114 : if(bNoFill)
1973 : {
1974 : // see comment above about OBJ_PLIN
1975 : pObj = new SdrPathObj(
1976 0 : aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN,
1977 0 : aNewB2DPolyPolygon, dBrightness);
1978 0 : aTempSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
1979 : }
1980 : else
1981 : {
1982 114 : aNewB2DPolyPolygon.setClosed(true);
1983 114 : pObj = new SdrPathObj(OBJ_POLY, aNewB2DPolyPolygon, dBrightness);
1984 : }
1985 :
1986 114 : if(bNoStroke)
1987 : {
1988 0 : aTempSet.Put(XLineStyleItem(XLINE_NONE));
1989 : }
1990 :
1991 114 : if(pObj)
1992 : {
1993 114 : pObj->SetMergedItemSet(aTempSet);
1994 114 : rObjectList.push_back(pObj);
1995 114 : }
1996 : }
1997 3066 : }
1998 3066 : }
1999 :
2000 106 : void CorrectCalloutArrows( MSO_SPT eSpType, sal_uInt32 nLineObjectCount, std::vector< SdrPathObj* >& vObjectList )
2001 : {
2002 106 : bool bAccent = false;
2003 106 : switch( eSpType )
2004 : {
2005 : case mso_sptCallout1 :
2006 : case mso_sptBorderCallout1 :
2007 : case mso_sptCallout90 :
2008 : case mso_sptBorderCallout90 :
2009 : default:
2010 106 : break;
2011 :
2012 : case mso_sptAccentCallout1 :
2013 : case mso_sptAccentBorderCallout1 :
2014 : case mso_sptAccentCallout90 :
2015 : case mso_sptAccentBorderCallout90 :
2016 : {
2017 0 : sal_uInt32 i, nLine = 0;
2018 0 : for ( i = 0; i < vObjectList.size(); i++ )
2019 : {
2020 0 : SdrPathObj* pObj( vObjectList[ i ] );
2021 0 : if(pObj->IsLine())
2022 : {
2023 0 : nLine++;
2024 0 : if ( nLine == nLineObjectCount )
2025 : {
2026 0 : pObj->ClearMergedItem( XATTR_LINESTART );
2027 0 : pObj->ClearMergedItem( XATTR_LINEEND );
2028 : }
2029 : }
2030 : }
2031 : }
2032 0 : break;
2033 :
2034 : // switch start & end
2035 : case mso_sptAccentCallout2 :
2036 : case mso_sptAccentBorderCallout2 :
2037 0 : bAccent = true;
2038 : //fall-through
2039 : case mso_sptCallout2 :
2040 : case mso_sptBorderCallout2 :
2041 : {
2042 0 : sal_uInt32 i, nLine = 0;
2043 0 : for ( i = 0; i < vObjectList.size(); i++ )
2044 : {
2045 0 : SdrPathObj* pObj( vObjectList[ i ] );
2046 0 : if(pObj->IsLine())
2047 : {
2048 0 : nLine++;
2049 0 : if ( nLine == 1 )
2050 0 : pObj->ClearMergedItem( XATTR_LINEEND );
2051 0 : else if ( ( bAccent && ( nLine == nLineObjectCount - 1 ) ) || ( !bAccent && ( nLine == nLineObjectCount ) ) )
2052 0 : pObj->ClearMergedItem( XATTR_LINESTART );
2053 : else
2054 : {
2055 0 : pObj->ClearMergedItem( XATTR_LINESTART );
2056 0 : pObj->ClearMergedItem( XATTR_LINEEND );
2057 : }
2058 : }
2059 : }
2060 : }
2061 0 : break;
2062 :
2063 : case mso_sptAccentCallout3 :
2064 : case mso_sptAccentBorderCallout3 :
2065 0 : bAccent = false;
2066 : //fall-through
2067 : case mso_sptCallout3 :
2068 : case mso_sptBorderCallout3 :
2069 : {
2070 0 : sal_uInt32 i, nLine = 0;
2071 0 : for ( i = 0; i < vObjectList.size(); i++ )
2072 : {
2073 0 : SdrPathObj* pObj( vObjectList[ i ] );
2074 0 : if(pObj->IsLine())
2075 : {
2076 0 : if ( nLine )
2077 : {
2078 0 : pObj->ClearMergedItem( XATTR_LINESTART );
2079 0 : pObj->ClearMergedItem( XATTR_LINEEND );
2080 : }
2081 : else
2082 0 : EnhancedCustomShape2d::SwapStartAndEndArrow( pObj );
2083 :
2084 0 : nLine++;
2085 : }
2086 : }
2087 : }
2088 0 : break;
2089 : }
2090 106 : }
2091 :
2092 4538 : void EnhancedCustomShape2d::AdaptObjColor(SdrPathObj& rObj, const SfxItemSet& rCustomShapeSet,
2093 : sal_uInt32& nColorIndex, sal_uInt32 nColorCount)
2094 : {
2095 4538 : if ( !rObj.IsLine() )
2096 : {
2097 3772 : const drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(rObj.GetMergedItem(XATTR_FILLSTYLE)).GetValue();
2098 3772 : switch( eFillStyle )
2099 : {
2100 : default:
2101 : case drawing::FillStyle_SOLID:
2102 : {
2103 3404 : Color aFillColor;
2104 3404 : if ( nColorCount || rObj.GetBrightness() != 1.0 )
2105 : {
2106 : aFillColor = GetColorData(
2107 24 : static_cast<const XFillColorItem&>(rCustomShapeSet.Get( XATTR_FILLCOLOR )).GetColorValue(),
2108 48 : std::min(nColorIndex, nColorCount-1), rObj.GetBrightness() );
2109 24 : rObj.SetMergedItem( XFillColorItem( "", aFillColor ) );
2110 : }
2111 3404 : break;
2112 : }
2113 : case drawing::FillStyle_GRADIENT:
2114 : {
2115 274 : XGradient aXGradient(static_cast<const XFillGradientItem&>(rObj.GetMergedItem(XATTR_FILLGRADIENT)).GetGradientValue());
2116 274 : if ( nColorCount || rObj.GetBrightness() != 1.0 )
2117 : {
2118 : aXGradient.SetStartColor(
2119 : GetColorData(
2120 : aXGradient.GetStartColor(),
2121 0 : std::min(nColorIndex, nColorCount-1), rObj.GetBrightness() ));
2122 : aXGradient.SetEndColor(
2123 : GetColorData(
2124 : aXGradient.GetEndColor(),
2125 0 : std::min(nColorIndex, nColorCount-1), rObj.GetBrightness() ));
2126 : }
2127 :
2128 274 : rObj.SetMergedItem( XFillGradientItem( "", aXGradient ) );
2129 274 : break;
2130 : }
2131 : case drawing::FillStyle_HATCH:
2132 : {
2133 4 : XHatch aXHatch(static_cast<const XFillHatchItem&>(rObj.GetMergedItem(XATTR_FILLHATCH)).GetHatchValue());
2134 4 : if ( nColorCount || rObj.GetBrightness() != 1.0 )
2135 : {
2136 : aXHatch.SetColor(
2137 : GetColorData(
2138 : aXHatch.GetColor(),
2139 0 : std::min(nColorIndex, nColorCount-1), rObj.GetBrightness() ));
2140 : }
2141 :
2142 4 : rObj.SetMergedItem( XFillHatchItem( "", aXHatch ) );
2143 4 : break;
2144 : }
2145 : case drawing::FillStyle_BITMAP:
2146 : {
2147 90 : if ( nColorCount || rObj.GetBrightness() != 1.0 )
2148 : {
2149 0 : Bitmap aBitmap(static_cast<const XFillBitmapItem&>(rObj.GetMergedItem(XATTR_FILLBITMAP)).GetGraphicObject().GetGraphic().GetBitmapEx().GetBitmap());
2150 :
2151 : aBitmap.Adjust(
2152 : static_cast< short > ( GetLuminanceChange(
2153 0 : std::min(nColorIndex, nColorCount-1))));
2154 :
2155 0 : rObj.SetMergedItem(XFillBitmapItem(OUString(), Graphic(aBitmap)));
2156 : }
2157 :
2158 90 : break;
2159 : }
2160 : }
2161 :
2162 3772 : if ( nColorIndex < nColorCount )
2163 24 : nColorIndex++;
2164 : }
2165 4538 : }
2166 :
2167 7362 : SdrObject* EnhancedCustomShape2d::CreatePathObj( bool bLineGeometryNeededOnly )
2168 : {
2169 7362 : sal_Int32 nCoordSize = seqCoordinates.getLength();
2170 7362 : if ( !nCoordSize )
2171 4596 : return NULL;
2172 :
2173 2766 : sal_uInt16 nSrcPt = 0;
2174 2766 : sal_uInt16 nSegmentInd = 0;
2175 :
2176 2766 : std::vector< SdrPathObj* > vObjectList;
2177 2766 : bool bSortFilledObjectsToBack = SortFilledObjectsToBackByDefault( eSpType );
2178 :
2179 2766 : sal_Int32 nSubPathIndex = 0;
2180 :
2181 8598 : while( nSegmentInd <= seqSegments.getLength() )
2182 : {
2183 3066 : CreateSubPath( nSrcPt, nSegmentInd, vObjectList, bLineGeometryNeededOnly, bSortFilledObjectsToBack, nSubPathIndex );
2184 3066 : nSubPathIndex ++;
2185 : }
2186 :
2187 2766 : SdrObject* pRet = NULL;
2188 :
2189 2766 : if ( !vObjectList.empty() )
2190 : {
2191 2766 : const SfxItemSet& rCustomShapeSet = pCustomShapeObj->GetMergedItemSet();
2192 2766 : sal_uInt32 nColorCount = nColorData >> 28;
2193 2766 : sal_uInt32 nColorIndex = 0;
2194 :
2195 : // #i37011# remove invisible objects
2196 2766 : if(!vObjectList.empty())
2197 : {
2198 2766 : std::vector< SdrPathObj* > vTempList;
2199 :
2200 7698 : for(size_t i = 0; i < vObjectList.size(); ++i)
2201 : {
2202 4932 : SdrPathObj* pObj(vObjectList[i]);
2203 4932 : const XLineStyle eLineStyle =static_cast<const XLineStyleItem&>(pObj->GetMergedItem(XATTR_LINESTYLE)).GetValue();
2204 4932 : const drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue();
2205 :
2206 : //SJ: #i40600# if bLineGeometryNeededOnly is set linystyle does not matter
2207 4932 : if( !bLineGeometryNeededOnly && ( XLINE_NONE == eLineStyle ) && ( drawing::FillStyle_NONE == eFillStyle ) )
2208 182 : delete pObj;
2209 : else
2210 4750 : vTempList.push_back(pObj);
2211 : }
2212 :
2213 2766 : vObjectList = vTempList;
2214 : }
2215 :
2216 2766 : if(1L == vObjectList.size())
2217 : {
2218 : // a single object, correct some values
2219 904 : AdaptObjColor(*vObjectList[0L],rCustomShapeSet,nColorIndex,nColorCount);
2220 : }
2221 : else
2222 : {
2223 1862 : sal_Int32 nLineObjectCount = 0;
2224 1862 : sal_Int32 nAreaObjectCount = 0;
2225 :
2226 : // correct some values and collect content data
2227 5708 : for ( size_t i = 0; i < vObjectList.size(); ++i )
2228 : {
2229 3846 : SdrPathObj* pObj( vObjectList[ i ] );
2230 :
2231 3846 : if(pObj->IsLine())
2232 : {
2233 212 : nLineObjectCount++;
2234 : }
2235 : else
2236 : {
2237 3634 : nAreaObjectCount++;
2238 3634 : AdaptObjColor(*pObj,rCustomShapeSet,nColorIndex,nColorCount);
2239 : }
2240 : }
2241 :
2242 : // #i88870# correct line arrows for callouts
2243 1862 : if ( nLineObjectCount )
2244 106 : CorrectCalloutArrows( eSpType, nLineObjectCount, vObjectList );
2245 :
2246 : // sort objects so that filled ones are in front. Necessary
2247 : // for some strange objects
2248 1862 : if ( bSortFilledObjectsToBack )
2249 : {
2250 1732 : std::vector< SdrPathObj* > vTempList;
2251 1732 : vTempList.reserve(vObjectList.size());
2252 :
2253 5354 : for ( size_t i = 0; i < vObjectList.size(); ++i )
2254 : {
2255 3622 : SdrPathObj* pObj( vObjectList[ i ] );
2256 :
2257 3622 : if ( !pObj->IsLine() )
2258 : {
2259 3602 : vTempList.push_back(pObj);
2260 : }
2261 : }
2262 :
2263 5354 : for ( size_t i = 0; i < vObjectList.size(); ++i )
2264 : {
2265 3622 : SdrPathObj* pObj( vObjectList[ i ] );
2266 :
2267 3622 : if ( pObj->IsLine() )
2268 : {
2269 20 : vTempList.push_back(pObj);
2270 : }
2271 : }
2272 :
2273 1732 : vObjectList = vTempList;
2274 : }
2275 : }
2276 : }
2277 :
2278 : // #i37011#
2279 2766 : if(!vObjectList.empty())
2280 : {
2281 : // copy remaining objects to pRet
2282 2654 : if(vObjectList.size() > 1)
2283 : {
2284 1750 : pRet = new SdrObjGroup;
2285 :
2286 5596 : for (size_t i = 0; i < vObjectList.size(); ++i)
2287 : {
2288 3846 : SdrObject* pObj(vObjectList[i]);
2289 3846 : pRet->GetSubList()->NbcInsertObject(pObj);
2290 : }
2291 : }
2292 904 : else if(1 == vObjectList.size())
2293 : {
2294 904 : pRet = vObjectList[0L];
2295 : }
2296 :
2297 2654 : if(pRet)
2298 : {
2299 : // move to target position
2300 2654 : Rectangle aCurRect(pRet->GetSnapRect());
2301 2654 : aCurRect.Move(aLogicRect.Left(), aLogicRect.Top());
2302 2654 : pRet->NbcSetSnapRect(aCurRect);
2303 : }
2304 : }
2305 :
2306 2766 : return pRet;
2307 : }
2308 :
2309 10172 : SdrObject* EnhancedCustomShape2d::CreateObject( bool bLineGeometryNeededOnly )
2310 : {
2311 10172 : SdrObject* pRet = NULL;
2312 :
2313 10172 : if ( eSpType == mso_sptRectangle )
2314 : {
2315 2810 : pRet = new SdrRectObj( aLogicRect );
2316 2810 : pRet->SetMergedItemSet( *this );
2317 : }
2318 10172 : if ( !pRet )
2319 7362 : pRet = CreatePathObj( bLineGeometryNeededOnly );
2320 :
2321 10172 : return pRet;
2322 : }
2323 :
2324 5448 : void EnhancedCustomShape2d::ApplyGluePoints( SdrObject* pObj )
2325 : {
2326 5448 : if ( pObj && seqGluePoints.getLength() )
2327 : {
2328 28 : sal_uInt32 i, nCount = seqGluePoints.getLength();
2329 188 : for ( i = 0; i < nCount; i++ )
2330 : {
2331 160 : SdrGluePoint aGluePoint;
2332 :
2333 160 : aGluePoint.SetPos( GetPoint( seqGluePoints[ i ], true, true ) );
2334 160 : aGluePoint.SetPercent( false );
2335 160 : aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
2336 160 : aGluePoint.SetEscDir( SDRESC_SMART );
2337 160 : SdrGluePointList* pList = pObj->ForceGluePointList();
2338 160 : if( pList )
2339 160 : /* sal_uInt16 nId = */ pList->Insert( aGluePoint );
2340 : }
2341 : }
2342 5448 : }
2343 :
2344 10156 : bool EnhancedCustomShape2d::IsPostRotate() const
2345 : {
2346 10156 : return pCustomShapeObj->ISA( SdrObjCustomShape ) && static_cast<SdrObjCustomShape*>(pCustomShapeObj)->IsPostRotate();
2347 : }
2348 :
2349 16 : SdrObject* EnhancedCustomShape2d::CreateLineGeometry()
2350 : {
2351 16 : return CreateObject( true );
2352 651 : }
2353 :
2354 :
2355 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|