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/svdoashp.hxx>
21 : #include "svx/unoapi.hxx"
22 : #include <svx/unoshape.hxx>
23 : #include <ucbhelper/content.hxx>
24 : #include <unotools/datetime.hxx>
25 : #include <sfx2/lnkbase.hxx>
26 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 : #include <com/sun/star/drawing/XShape.hpp>
28 : #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
29 : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
30 : #include <com/sun/star/beans/PropertyValue.hpp>
31 : #include <com/sun/star/awt/Rectangle.hpp>
32 : #include <comphelper/processfactory.hxx>
33 : #include <svl/urihelper.hxx>
34 : #include <com/sun/star/uno/Sequence.h>
35 : #include <svx/svdogrp.hxx>
36 : #include <tools/helpers.hxx>
37 : #include <svx/svddrag.hxx>
38 : #include <svx/xpool.hxx>
39 : #include <svx/xpoly.hxx>
40 : #include <svx/svdmodel.hxx>
41 : #include <svx/svdpage.hxx>
42 : #include "svx/svditer.hxx"
43 : #include <svx/svdobj.hxx>
44 : #include <svx/svdtrans.hxx>
45 : #include <svx/svdetc.hxx>
46 : #include <svx/svdoedge.hxx>
47 : #include "svx/svdglob.hxx"
48 : #include "svx/svdstr.hrc"
49 : #include <editeng/eeitem.hxx>
50 : #include "editeng/editstat.hxx"
51 : #include <svx/svdoutl.hxx>
52 : #include <editeng/outlobj.hxx>
53 : #include <svx/sdtfchim.hxx>
54 : #include "svx/EnhancedCustomShapeGeometry.hxx"
55 : #include "svx/EnhancedCustomShapeTypeNames.hxx"
56 : #include "svx/EnhancedCustomShape2d.hxx"
57 : #include <com/sun/star/beans/PropertyValues.hpp>
58 : #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
59 : #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
60 : #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
61 : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
62 : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
63 : #include <editeng/writingmodeitem.hxx>
64 : #include <svx/xlnclit.hxx>
65 : #include <svx/svxids.hrc>
66 : #include <svl/whiter.hxx>
67 : #include <svx/sdr/properties/customshapeproperties.hxx>
68 : #include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx>
69 : #include <svx/xlntrit.hxx>
70 : #include <svx/xfltrit.hxx>
71 : #include <svx/xflclit.hxx>
72 : #include <svx/xflgrit.hxx>
73 : #include <svx/xflhtit.hxx>
74 : #include <svx/xbtmpit.hxx>
75 : #include <vcl/bmpacc.hxx>
76 : #include <svx/svdview.hxx>
77 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
78 : #include <basegfx/matrix/b2dhommatrix.hxx>
79 : #include <basegfx/matrix/b2dhommatrixtools.hxx>
80 : #include <basegfx/tools/unotools.hxx>
81 : #include "svdconv.hxx"
82 :
83 : using namespace ::com::sun::star;
84 : using namespace ::com::sun::star::uno;
85 : using namespace ::com::sun::star::lang;
86 : using namespace ::com::sun::star::beans;
87 : using namespace ::com::sun::star::drawing;
88 :
89 0 : static void lcl_ShapeSegmentFromBinary( EnhancedCustomShapeSegment& rSegInfo, sal_uInt16 nSDat )
90 : {
91 0 : switch( nSDat >> 8 )
92 : {
93 : case 0x00 :
94 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO;
95 0 : rSegInfo.Count = nSDat & 0xff;
96 0 : if ( !rSegInfo.Count )
97 0 : rSegInfo.Count = 1;
98 0 : break;
99 : case 0x20 :
100 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
101 0 : rSegInfo.Count = nSDat & 0xff;
102 0 : if ( !rSegInfo.Count )
103 0 : rSegInfo.Count = 1;
104 0 : break;
105 : case 0x40 :
106 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
107 0 : rSegInfo.Count = nSDat & 0xff;
108 0 : if ( !rSegInfo.Count )
109 0 : rSegInfo.Count = 1;
110 0 : break;
111 : case 0x60 :
112 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
113 0 : rSegInfo.Count = 0;
114 0 : break;
115 : case 0x80 :
116 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
117 0 : rSegInfo.Count = 0;
118 0 : break;
119 : case 0xa1 :
120 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
121 0 : rSegInfo.Count = ( nSDat & 0xff ) / 3;
122 0 : break;
123 : case 0xa2 :
124 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
125 0 : rSegInfo.Count = ( nSDat & 0xff ) / 3;
126 0 : break;
127 : case 0xa3 :
128 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
129 0 : rSegInfo.Count = ( nSDat & 0xff ) >> 2;
130 0 : break;
131 : case 0xa4 :
132 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC;
133 0 : rSegInfo.Count = ( nSDat & 0xff ) >> 2;
134 0 : break;
135 : case 0xa5 :
136 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
137 0 : rSegInfo.Count = ( nSDat & 0xff ) >> 2;
138 0 : break;
139 : case 0xa6 :
140 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
141 0 : rSegInfo.Count = ( nSDat & 0xff ) >> 2;
142 0 : break;
143 : case 0xa7 :
144 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
145 0 : rSegInfo.Count = nSDat & 0xff;
146 0 : break;
147 : case 0xa8 :
148 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
149 0 : rSegInfo.Count = nSDat & 0xff;
150 0 : break;
151 : case 0xaa :
152 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
153 0 : rSegInfo.Count = 0;
154 0 : break;
155 : case 0xab :
156 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
157 0 : rSegInfo.Count = 0;
158 0 : break;
159 : default:
160 : case 0xf8 :
161 0 : rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN;
162 0 : rSegInfo.Count = nSDat;
163 0 : break;
164 : }
165 0 : return;
166 : }
167 :
168 0 : static MSO_SPT ImpGetCustomShapeType( const SdrObjCustomShape& rCustoShape )
169 : {
170 0 : MSO_SPT eRetValue = mso_sptNil;
171 :
172 0 : OUString aEngine( ( (SdrCustomShapeEngineItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ) ).GetValue() );
173 0 : if ( aEngine.isEmpty() || aEngine == "com.sun.star.drawing.EnhancedCustomShapeEngine" )
174 : {
175 0 : OUString sShapeType;
176 0 : const OUString sType( "Type" );
177 0 : SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
178 0 : Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
179 0 : if ( pAny && ( *pAny >>= sShapeType ) )
180 0 : eRetValue = EnhancedCustomShapeTypeNames::Get( sShapeType );
181 : }
182 0 : return eRetValue;
183 : };
184 :
185 0 : static bool ImpVerticalSwitch( const SdrObjCustomShape& rCustoShape )
186 : {
187 0 : bool bRet = false;
188 0 : MSO_SPT eShapeType( ImpGetCustomShapeType( rCustoShape ) );
189 0 : switch( eShapeType )
190 : {
191 : case mso_sptAccentBorderCallout90 : // 2 ortho
192 : case mso_sptBorderCallout1 : // 2 diag
193 : case mso_sptBorderCallout2 : // 3
194 : {
195 0 : bRet = true;
196 : }
197 0 : break;
198 0 : default: break;
199 : }
200 0 : return bRet;
201 : }
202 :
203 : // #i37011# create a clone with all attributes changed to shadow attributes
204 : // and translation executed, too.
205 0 : SdrObject* ImpCreateShadowObjectClone(const SdrObject& rOriginal, const SfxItemSet& rOriginalSet)
206 : {
207 0 : SdrObject* pRetval = 0L;
208 0 : const bool bShadow(((SdrShadowItem&)rOriginalSet.Get(SDRATTR_SHADOW)).GetValue());
209 :
210 0 : if(bShadow)
211 : {
212 : // create a shadow representing object
213 0 : const sal_Int32 nXDist(((SdrShadowXDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWXDIST))).GetValue());
214 0 : const sal_Int32 nYDist(((SdrShadowYDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWYDIST))).GetValue());
215 0 : const ::Color aShadowColor(((SdrShadowColorItem&)(rOriginalSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue());
216 0 : const sal_uInt16 nShadowTransparence(((SdrShadowTransparenceItem&)(rOriginalSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue());
217 0 : pRetval = rOriginal.Clone();
218 : DBG_ASSERT(pRetval, "ImpCreateShadowObjectClone: Could not clone object (!)");
219 :
220 : // look for used stuff
221 0 : SdrObjListIter aIterator(rOriginal);
222 0 : bool bLineUsed(false);
223 0 : bool bAllFillUsed(false);
224 0 : bool bSolidFillUsed(false);
225 0 : bool bGradientFillUsed(false);
226 0 : bool bHatchFillUsed(false);
227 0 : bool bBitmapFillUsed(false);
228 :
229 0 : while(aIterator.IsMore())
230 : {
231 0 : SdrObject* pObj = aIterator.Next();
232 0 : XFillStyle eFillStyle = ((XFillStyleItem&)(pObj->GetMergedItem(XATTR_FILLSTYLE))).GetValue();
233 :
234 0 : if(!bLineUsed)
235 : {
236 0 : XLineStyle eLineStyle = ((XLineStyleItem&)(pObj->GetMergedItem(XATTR_LINESTYLE))).GetValue();
237 :
238 0 : if(XLINE_NONE != eLineStyle)
239 : {
240 0 : bLineUsed = true;
241 : }
242 : }
243 :
244 0 : if(!bAllFillUsed)
245 : {
246 0 : if(!bSolidFillUsed && XFILL_SOLID == eFillStyle)
247 : {
248 0 : bSolidFillUsed = true;
249 0 : bAllFillUsed = (bSolidFillUsed && bGradientFillUsed && bHatchFillUsed && bBitmapFillUsed);
250 : }
251 0 : if(!bGradientFillUsed && XFILL_GRADIENT == eFillStyle)
252 : {
253 0 : bGradientFillUsed = true;
254 0 : bAllFillUsed = (bSolidFillUsed && bGradientFillUsed && bHatchFillUsed && bBitmapFillUsed);
255 : }
256 0 : if(!bHatchFillUsed && XFILL_HATCH == eFillStyle)
257 : {
258 0 : bHatchFillUsed = true;
259 0 : bAllFillUsed = (bSolidFillUsed && bGradientFillUsed && bHatchFillUsed && bBitmapFillUsed);
260 : }
261 0 : if(!bBitmapFillUsed && XFILL_BITMAP == eFillStyle)
262 : {
263 0 : bBitmapFillUsed = true;
264 0 : bAllFillUsed = (bSolidFillUsed && bGradientFillUsed && bHatchFillUsed && bBitmapFillUsed);
265 : }
266 : }
267 : }
268 :
269 : // translate to shadow coordinates
270 0 : pRetval->NbcMove(Size(nXDist, nYDist));
271 :
272 : // set items as needed
273 0 : SfxItemSet aTempSet(rOriginalSet);
274 :
275 : // if a SvxWritingModeItem (Top->Bottom) is set the text object
276 : // is creating a paraobject, but paraobjects can not be created without model. So
277 : // we are preventing the crash by setting the writing mode always left to right,
278 : // this is not bad since our shadow geometry does not contain text.
279 0 : aTempSet.Put( SvxWritingModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION ) );
280 :
281 : // no shadow
282 0 : aTempSet.Put(SdrShadowItem(false));
283 0 : aTempSet.Put(SdrShadowXDistItem(0L));
284 0 : aTempSet.Put(SdrShadowYDistItem(0L));
285 :
286 : // line color and transparency like shadow
287 0 : if(bLineUsed)
288 : {
289 0 : aTempSet.Put(XLineColorItem(OUString(), aShadowColor));
290 0 : aTempSet.Put(XLineTransparenceItem(nShadowTransparence));
291 : }
292 :
293 : // fill color and transparency like shadow
294 0 : if(bSolidFillUsed)
295 : {
296 0 : aTempSet.Put(XFillColorItem(OUString(), aShadowColor));
297 0 : aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
298 : }
299 :
300 : // gradient and transparency like shadow
301 0 : if(bGradientFillUsed)
302 : {
303 0 : XGradient aGradient(((XFillGradientItem&)(rOriginalSet.Get(XATTR_FILLGRADIENT))).GetGradientValue());
304 0 : sal_uInt8 nStartLuminance(aGradient.GetStartColor().GetLuminance());
305 0 : sal_uInt8 nEndLuminance(aGradient.GetEndColor().GetLuminance());
306 :
307 0 : if(aGradient.GetStartIntens() != 100)
308 : {
309 0 : nStartLuminance = (sal_uInt8)(nStartLuminance * ((double)aGradient.GetStartIntens() / 100.0));
310 : }
311 :
312 0 : if(aGradient.GetEndIntens() != 100)
313 : {
314 0 : nEndLuminance = (sal_uInt8)(nEndLuminance * ((double)aGradient.GetEndIntens() / 100.0));
315 : }
316 :
317 : ::Color aStartColor(
318 0 : (sal_uInt8)((nStartLuminance * aShadowColor.GetRed()) / 256),
319 0 : (sal_uInt8)((nStartLuminance * aShadowColor.GetGreen()) / 256),
320 0 : (sal_uInt8)((nStartLuminance * aShadowColor.GetBlue()) / 256));
321 :
322 : ::Color aEndColor(
323 0 : (sal_uInt8)((nEndLuminance * aShadowColor.GetRed()) / 256),
324 0 : (sal_uInt8)((nEndLuminance * aShadowColor.GetGreen()) / 256),
325 0 : (sal_uInt8)((nEndLuminance * aShadowColor.GetBlue()) / 256));
326 :
327 0 : aGradient.SetStartColor(aStartColor);
328 0 : aGradient.SetEndColor(aEndColor);
329 0 : aTempSet.Put(XFillGradientItem(aGradient));
330 0 : aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
331 : }
332 :
333 : // hatch and transparency like shadow
334 0 : if(bHatchFillUsed)
335 : {
336 0 : XHatch aHatch(((XFillHatchItem&)(rOriginalSet.Get(XATTR_FILLHATCH))).GetHatchValue());
337 0 : aHatch.SetColor(aShadowColor);
338 0 : aTempSet.Put(XFillHatchItem(aTempSet.GetPool(), aHatch));
339 0 : aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
340 : }
341 :
342 : // bitmap and transparency like shadow
343 0 : if(bBitmapFillUsed)
344 : {
345 0 : GraphicObject aGraphicObject(((XFillBitmapItem&)(rOriginalSet.Get(XATTR_FILLBITMAP))).GetGraphicObject());
346 0 : const BitmapEx aBitmapEx(aGraphicObject.GetGraphic().GetBitmapEx());
347 0 : Bitmap aBitmap(aBitmapEx.GetBitmap());
348 :
349 0 : if(!aBitmap.IsEmpty())
350 : {
351 0 : BitmapReadAccess* pReadAccess = aBitmap.AcquireReadAccess();
352 :
353 0 : if(pReadAccess)
354 : {
355 0 : Bitmap aDestBitmap(aBitmap.GetSizePixel(), 24L);
356 0 : BitmapWriteAccess* pWriteAccess = aDestBitmap.AcquireWriteAccess();
357 :
358 0 : if(pWriteAccess)
359 : {
360 0 : for(sal_Int32 y(0L); y < pReadAccess->Height(); y++)
361 : {
362 0 : for(sal_Int32 x(0L); x < pReadAccess->Width(); x++)
363 : {
364 0 : sal_uInt16 nLuminance((sal_uInt16)pReadAccess->GetLuminance(y, x) + 1);
365 : const BitmapColor aDestColor(
366 0 : (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetRed()) >> 8L),
367 0 : (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetGreen()) >> 8L),
368 0 : (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetBlue()) >> 8L));
369 0 : pWriteAccess->SetPixel(y, x, aDestColor);
370 0 : }
371 : }
372 :
373 0 : aDestBitmap.ReleaseAccess(pWriteAccess);
374 : }
375 :
376 0 : aBitmap.ReleaseAccess(pReadAccess);
377 :
378 0 : if(aBitmapEx.IsTransparent())
379 : {
380 0 : if(aBitmapEx.IsAlpha())
381 : {
382 0 : aGraphicObject.SetGraphic(Graphic(BitmapEx(aDestBitmap, aBitmapEx.GetAlpha())));
383 : }
384 : else
385 : {
386 0 : aGraphicObject.SetGraphic(Graphic(BitmapEx(aDestBitmap, aBitmapEx.GetMask())));
387 : }
388 : }
389 : else
390 : {
391 0 : aGraphicObject.SetGraphic(Graphic(aDestBitmap));
392 0 : }
393 : }
394 : }
395 :
396 0 : aTempSet.Put(XFillBitmapItem(aTempSet.GetPool(), aGraphicObject));
397 0 : aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
398 : }
399 :
400 : // set attributes and paint shadow object
401 0 : pRetval->SetMergedItemSet( aTempSet );
402 : }
403 0 : return pRetval;
404 : }
405 :
406 :
407 :
408 0 : Reference< XCustomShapeEngine > SdrObjCustomShape::GetCustomShapeEngine() const
409 : {
410 0 : if (mxCustomShapeEngine.is())
411 0 : return mxCustomShapeEngine;
412 :
413 0 : OUString aEngine(((SdrCustomShapeEngineItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE )).GetValue());
414 0 : if ( aEngine.isEmpty() )
415 0 : aEngine = "com.sun.star.drawing.EnhancedCustomShapeEngine";
416 :
417 0 : Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
418 :
419 0 : Reference< XShape > aXShape = GetXShapeForSdrObject(const_cast<SdrObjCustomShape*>(this));
420 0 : if ( aXShape.is() )
421 : {
422 0 : if ( !aEngine.isEmpty() )
423 : {
424 0 : Sequence< Any > aArgument( 1 );
425 0 : Sequence< PropertyValue > aPropValues( 1 );
426 0 : aPropValues[ 0 ].Name = "CustomShape";
427 0 : aPropValues[ 0 ].Value <<= aXShape;
428 0 : aArgument[ 0 ] <<= aPropValues;
429 0 : Reference< XInterface > xInterface( xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aEngine, aArgument, xContext ) );
430 0 : if ( xInterface.is() )
431 0 : mxCustomShapeEngine = Reference< XCustomShapeEngine >( xInterface, UNO_QUERY );
432 : }
433 : }
434 :
435 0 : return mxCustomShapeEngine;
436 : }
437 :
438 0 : const SdrObject* SdrObjCustomShape::GetSdrObjectFromCustomShape() const
439 : {
440 0 : if ( !mXRenderedCustomShape.is() )
441 : {
442 0 : Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine() );
443 0 : if ( xCustomShapeEngine.is() )
444 0 : ((SdrObjCustomShape*)this)->mXRenderedCustomShape = xCustomShapeEngine->render();
445 : }
446 0 : SdrObject* pRenderedCustomShape = mXRenderedCustomShape.is()
447 0 : ? GetSdrObjectFromXShape( mXRenderedCustomShape )
448 0 : : NULL;
449 0 : return pRenderedCustomShape;
450 : }
451 :
452 : // #i37011# Shadow geometry creation
453 0 : const SdrObject* SdrObjCustomShape::GetSdrObjectShadowFromCustomShape() const
454 : {
455 0 : if(!mpLastShadowGeometry)
456 : {
457 0 : const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
458 0 : if(pSdrObject)
459 : {
460 0 : const SfxItemSet& rOriginalSet = GetObjectItemSet();
461 0 : const bool bShadow(((SdrShadowItem&)rOriginalSet.Get( SDRATTR_SHADOW )).GetValue());
462 :
463 0 : if(bShadow)
464 : {
465 : // create a clone with all attributes changed to shadow attributes
466 : // and translation executed, too.
467 0 : ((SdrObjCustomShape*)this)->mpLastShadowGeometry = ImpCreateShadowObjectClone(*pSdrObject, rOriginalSet);
468 : }
469 : }
470 : }
471 :
472 0 : return mpLastShadowGeometry;
473 : }
474 :
475 0 : bool SdrObjCustomShape::IsTextPath() const
476 : {
477 0 : const OUString sTextPath( "TextPath" );
478 0 : bool bTextPathOn = false;
479 0 : SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
480 0 : Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
481 0 : if ( pAny )
482 0 : *pAny >>= bTextPathOn;
483 0 : return bTextPathOn;
484 : }
485 :
486 0 : bool SdrObjCustomShape::UseNoFillStyle() const
487 : {
488 0 : bool bRet = false;
489 0 : OUString sShapeType;
490 0 : const OUString sType( "Type" );
491 0 : SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
492 0 : Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
493 0 : if ( pAny )
494 0 : *pAny >>= sShapeType;
495 0 : bRet = IsCustomShapeFilledByDefault( EnhancedCustomShapeTypeNames::Get( sType ) ) == false;
496 :
497 0 : return bRet;
498 : }
499 :
500 0 : bool SdrObjCustomShape::IsMirroredX() const
501 : {
502 0 : bool bMirroredX = false;
503 0 : SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
504 0 : const OUString sMirroredX( "MirroredX" );
505 0 : com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
506 0 : if ( pAny )
507 0 : *pAny >>= bMirroredX;
508 0 : return bMirroredX;
509 : }
510 0 : bool SdrObjCustomShape::IsMirroredY() const
511 : {
512 0 : bool bMirroredY = false;
513 0 : SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
514 0 : const OUString sMirroredY( "MirroredY" );
515 0 : com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
516 0 : if ( pAny )
517 0 : *pAny >>= bMirroredY;
518 0 : return bMirroredY;
519 : }
520 0 : void SdrObjCustomShape::SetMirroredX( const bool bMirrorX )
521 : {
522 0 : SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
523 0 : const OUString sMirroredX( "MirroredX" );
524 0 : PropertyValue aPropVal;
525 0 : aPropVal.Name = sMirroredX;
526 0 : aPropVal.Value <<= bMirrorX;
527 0 : aGeometryItem.SetPropertyValue( aPropVal );
528 0 : SetMergedItem( aGeometryItem );
529 0 : }
530 0 : void SdrObjCustomShape::SetMirroredY( const bool bMirrorY )
531 : {
532 0 : SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
533 0 : const OUString sMirroredY( "MirroredY" );
534 0 : PropertyValue aPropVal;
535 0 : aPropVal.Name = sMirroredY;
536 0 : aPropVal.Value <<= bMirrorY;
537 0 : aGeometryItem.SetPropertyValue( aPropVal );
538 0 : SetMergedItem( aGeometryItem );
539 0 : }
540 :
541 0 : double SdrObjCustomShape::GetObjectRotation() const
542 : {
543 0 : return fObjectRotation;
544 : }
545 :
546 0 : bool SdrObjCustomShape::IsPostRotate() const
547 : {
548 : const com::sun::star::uno::Any* pAny;
549 0 : bool bPostRotate = false;
550 0 : SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
551 0 : pAny = rGeometryItem.GetPropertyValueByName( "IsPostRotateAngle" );
552 0 : if ( pAny )
553 0 : *pAny >>= bPostRotate;
554 0 : return bPostRotate;
555 : }
556 :
557 0 : double SdrObjCustomShape::GetExtraTextRotation( const bool bPreRotation ) const
558 : {
559 : const com::sun::star::uno::Any* pAny;
560 0 : SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
561 0 : const OUString sTextRotateAngle( "TextRotateAngle" );
562 0 : const OUString sTextPreRotateAngle( "TextPreRotateAngle" );
563 0 : pAny = rGeometryItem.GetPropertyValueByName( bPreRotation ? sTextPreRotateAngle : sTextRotateAngle );
564 0 : double fExtraTextRotateAngle = 0.0;
565 0 : if ( pAny )
566 0 : *pAny >>= fExtraTextRotateAngle;
567 0 : return fExtraTextRotateAngle;
568 : }
569 :
570 0 : bool SdrObjCustomShape::GetTextBounds( Rectangle& rTextBound ) const
571 : {
572 0 : bool bRet = false;
573 :
574 0 : Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine() );
575 0 : if ( xCustomShapeEngine.is() )
576 : {
577 0 : awt::Rectangle aR( xCustomShapeEngine->getTextBounds() );
578 0 : if ( aR.Width > 1 && aR.Height > 1 )
579 : {
580 0 : rTextBound = Rectangle( Point( aR.X, aR.Y ), Size( aR.Width, aR.Height ) );
581 0 : bRet = true;
582 : }
583 : }
584 0 : return bRet;
585 : }
586 0 : basegfx::B2DPolyPolygon SdrObjCustomShape::GetLineGeometry( const SdrObjCustomShape* pCustomShape, const bool bBezierAllowed )
587 : {
588 0 : basegfx::B2DPolyPolygon aRetval;
589 0 : Reference< XCustomShapeEngine > xCustomShapeEngine( pCustomShape->GetCustomShapeEngine() );
590 0 : if ( xCustomShapeEngine.is() )
591 : {
592 0 : com::sun::star::drawing::PolyPolygonBezierCoords aBezierCoords = xCustomShapeEngine->getLineGeometry();
593 : try
594 : {
595 0 : aRetval = basegfx::unotools::polyPolygonBezierToB2DPolyPolygon( aBezierCoords );
596 0 : if ( !bBezierAllowed && aRetval.areControlPointsUsed())
597 : {
598 0 : aRetval = basegfx::tools::adaptiveSubdivideByAngle(aRetval);
599 : }
600 : }
601 0 : catch ( const com::sun::star::lang::IllegalArgumentException & )
602 : {
603 0 : }
604 : }
605 0 : return aRetval;
606 : }
607 :
608 0 : std::vector< SdrCustomShapeInteraction > SdrObjCustomShape::GetInteractionHandles( const SdrObjCustomShape* pCustomShape ) const
609 : {
610 0 : std::vector< SdrCustomShapeInteraction > xRet;
611 : try
612 : {
613 0 : Reference< XCustomShapeEngine > xCustomShapeEngine( pCustomShape->GetCustomShapeEngine() );
614 0 : if ( xCustomShapeEngine.is() )
615 : {
616 : int i;
617 0 : Sequence< Reference< XCustomShapeHandle > > xInteractionHandles( xCustomShapeEngine->getInteraction() );
618 0 : for ( i = 0; i < xInteractionHandles.getLength(); i++ )
619 : {
620 0 : if ( xInteractionHandles[ i ].is() )
621 : {
622 0 : SdrCustomShapeInteraction aSdrCustomShapeInteraction;
623 0 : aSdrCustomShapeInteraction.xInteraction = xInteractionHandles[ i ];
624 0 : aSdrCustomShapeInteraction.aPosition = xInteractionHandles[ i ]->getPosition();
625 :
626 0 : sal_Int32 nMode = 0;
627 0 : switch( ImpGetCustomShapeType( *this ) )
628 : {
629 : case mso_sptAccentBorderCallout90 : // 2 ortho
630 : {
631 0 : if ( !i )
632 0 : nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
633 0 : else if ( i == 1)
634 0 : nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE | CUSTOMSHAPE_HANDLE_ORTHO4;
635 : }
636 0 : break;
637 :
638 : case mso_sptWedgeRectCallout :
639 : case mso_sptWedgeRRectCallout :
640 : case mso_sptCloudCallout :
641 : case mso_sptWedgeEllipseCallout :
642 : {
643 0 : if ( !i )
644 0 : nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED;
645 : }
646 0 : break;
647 :
648 : case mso_sptBorderCallout1 : // 2 diag
649 : {
650 0 : if ( !i )
651 0 : nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
652 0 : else if ( i == 1 )
653 0 : nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
654 : }
655 0 : break;
656 : case mso_sptBorderCallout2 : // 3
657 : {
658 0 : if ( !i )
659 0 : nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
660 0 : else if ( i == 2 )
661 0 : nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
662 : }
663 0 : break;
664 : case mso_sptCallout90 :
665 : case mso_sptAccentCallout90 :
666 : case mso_sptBorderCallout90 :
667 : case mso_sptCallout1 :
668 : case mso_sptCallout2 :
669 : case mso_sptCallout3 :
670 : case mso_sptAccentCallout1 :
671 : case mso_sptAccentCallout2 :
672 : case mso_sptAccentCallout3 :
673 : case mso_sptBorderCallout3 :
674 : case mso_sptAccentBorderCallout1 :
675 : case mso_sptAccentBorderCallout2 :
676 : case mso_sptAccentBorderCallout3 :
677 : {
678 0 : if ( !i )
679 0 : nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
680 : }
681 0 : break;
682 0 : default: break;
683 : }
684 0 : aSdrCustomShapeInteraction.nMode = nMode;
685 0 : xRet.push_back( aSdrCustomShapeInteraction );
686 : }
687 0 : }
688 0 : }
689 : }
690 0 : catch( const uno::RuntimeException& )
691 : {
692 : }
693 0 : return xRet;
694 : }
695 :
696 :
697 : // BaseProperties section
698 : #define DEFAULT_MINIMUM_SIGNED_COMPARE ((sal_Int32)0x80000000)
699 : #define DEFAULT_MAXIMUM_SIGNED_COMPARE ((sal_Int32)0x7fffffff)
700 :
701 0 : static sal_Int32 GetNumberOfProperties ( const SvxMSDffHandle* pData )
702 : {
703 0 : sal_Int32 nPropertiesNeeded=1; // position is always needed
704 0 : sal_Int32 nFlags = pData->nFlags;
705 :
706 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
707 0 : nPropertiesNeeded++;
708 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
709 0 : nPropertiesNeeded++;
710 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
711 0 : nPropertiesNeeded++;
712 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
713 : {
714 0 : nPropertiesNeeded++;
715 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
716 : {
717 0 : if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
718 0 : nPropertiesNeeded++;
719 0 : if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
720 0 : nPropertiesNeeded++;
721 : }
722 : }
723 0 : else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
724 : {
725 0 : if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
726 0 : nPropertiesNeeded++;
727 0 : if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
728 0 : nPropertiesNeeded++;
729 0 : if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
730 0 : nPropertiesNeeded++;
731 0 : if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
732 0 : nPropertiesNeeded++;
733 : }
734 :
735 0 : return nPropertiesNeeded;
736 : }
737 :
738 0 : static void lcl_ShapePropertiesFromDFF( const SvxMSDffHandle* pData, com::sun::star::beans::PropertyValues& rPropValues )
739 : {
740 0 : sal_Int32 nFlags = pData->nFlags, n=0;
741 :
742 : // POSITION
743 : {
744 0 : const OUString sPosition( "Position" );
745 0 : ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
746 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, true, true );
747 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, true, false );
748 0 : rPropValues[ n ].Name = sPosition;
749 0 : rPropValues[ n++ ].Value <<= aPosition;
750 : }
751 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
752 : {
753 0 : const OUString sMirroredX( "MirroredX" );
754 0 : bool bMirroredX = true;
755 0 : rPropValues[ n ].Name = sMirroredX;
756 0 : rPropValues[ n++ ].Value <<= bMirroredX;
757 : }
758 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
759 : {
760 0 : const OUString sMirroredY( "MirroredY" );
761 0 : bool bMirroredY = true;
762 0 : rPropValues[ n ].Name = sMirroredY;
763 0 : rPropValues[ n++ ].Value <<= bMirroredY;
764 : }
765 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
766 : {
767 0 : const OUString sSwitched( "Switched" );
768 0 : bool bSwitched = true;
769 0 : rPropValues[ n ].Name = sSwitched;
770 0 : rPropValues[ n++ ].Value <<= bSwitched;
771 : }
772 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
773 : {
774 0 : const OUString sPolar( "Polar" );
775 0 : ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter;
776 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First, pData->nCenterX,
777 0 : ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, true );
778 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY,
779 0 : ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, false );
780 0 : rPropValues[ n ].Name = sPolar;
781 0 : rPropValues[ n++ ].Value <<= aCenter;
782 0 : if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
783 : {
784 0 : if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
785 : {
786 0 : const OUString sRadiusRangeMinimum( "RadiusRangeMinimum" );
787 0 : ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
788 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin,
789 0 : ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, true );
790 0 : rPropValues[ n ].Name = sRadiusRangeMinimum;
791 0 : rPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
792 : }
793 0 : if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
794 : {
795 0 : const OUString sRadiusRangeMaximum( "RadiusRangeMaximum" );
796 0 : ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
797 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax,
798 0 : ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, false );
799 0 : rPropValues[ n ].Name = sRadiusRangeMaximum;
800 0 : rPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
801 : }
802 0 : }
803 : }
804 0 : else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
805 : {
806 0 : if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
807 : {
808 0 : const OUString sRangeXMinimum( "RangeXMinimum" );
809 0 : ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum;
810 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin,
811 0 : ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, true );
812 0 : rPropValues[ n ].Name = sRangeXMinimum;
813 0 : rPropValues[ n++ ].Value <<= aRangeXMinimum;
814 : }
815 0 : if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
816 : {
817 0 : const OUString sRangeXMaximum( "RangeXMaximum" );
818 0 : ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum;
819 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax,
820 0 : ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, false );
821 0 : rPropValues[ n ].Name = sRangeXMaximum;
822 0 : rPropValues[ n++ ].Value <<= aRangeXMaximum;
823 : }
824 0 : if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
825 : {
826 0 : const OUString sRangeYMinimum( "RangeYMinimum" );
827 0 : ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum;
828 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin,
829 0 : ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, true );
830 0 : rPropValues[ n ].Name = sRangeYMinimum;
831 0 : rPropValues[ n++ ].Value <<= aRangeYMinimum;
832 : }
833 0 : if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
834 : {
835 0 : const OUString sRangeYMaximum( "RangeYMaximum" );
836 0 : ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum;
837 : EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax,
838 0 : ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, false );
839 0 : rPropValues[ n ].Name = sRangeYMaximum;
840 0 : rPropValues[ n++ ].Value <<= aRangeYMaximum;
841 : }
842 : }
843 0 : return;
844 : }
845 :
846 0 : sdr::properties::BaseProperties* SdrObjCustomShape::CreateObjectSpecificProperties()
847 : {
848 0 : return new sdr::properties::CustomShapeProperties(*this);
849 : }
850 :
851 0 : TYPEINIT1(SdrObjCustomShape,SdrTextObj);
852 0 : SdrObjCustomShape::SdrObjCustomShape() :
853 : SdrTextObj(),
854 : fObjectRotation( 0.0 ),
855 0 : mpLastShadowGeometry(0L)
856 : {
857 0 : bClosedObj = true; // custom shapes may be filled
858 0 : bTextFrame = true;
859 0 : }
860 :
861 0 : SdrObjCustomShape::~SdrObjCustomShape()
862 : {
863 : // delete buffered display geometry
864 0 : InvalidateRenderGeometry();
865 0 : }
866 :
867 0 : void SdrObjCustomShape::MergeDefaultAttributes( const OUString* pType )
868 : {
869 0 : PropertyValue aPropVal;
870 0 : OUString sShapeType;
871 0 : const OUString sType( "Type" );
872 0 : SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
873 0 : if ( pType && !pType->isEmpty() )
874 : {
875 0 : sal_Int32 nType = pType->toInt32();
876 0 : if ( nType )
877 0 : sShapeType = EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT >( nType ) );
878 : else
879 0 : sShapeType = *pType;
880 :
881 0 : aPropVal.Name = sType;
882 0 : aPropVal.Value <<= sShapeType;
883 0 : aGeometryItem.SetPropertyValue( aPropVal );
884 : }
885 : else
886 : {
887 0 : Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
888 0 : if ( pAny )
889 0 : *pAny >>= sShapeType;
890 : }
891 0 : MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
892 :
893 0 : const sal_Int32* pDefData = NULL;
894 0 : const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
895 0 : if ( pDefCustomShape )
896 0 : pDefData = pDefCustomShape->pDefData;
897 :
898 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
899 :
900 :
901 : // AdjustmentValues
902 :
903 0 : const OUString sAdjustmentValues( "AdjustmentValues" );
904 0 : const Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
905 0 : if ( pAny )
906 0 : *pAny >>= seqAdjustmentValues;
907 0 : if ( pDefCustomShape && pDefData ) // now check if we have to default some adjustment values
908 : {
909 : // first check if there are adjustment values are to be appended
910 0 : sal_Int32 i, nAdjustmentValues = seqAdjustmentValues.getLength();
911 0 : sal_Int32 nAdjustmentDefaults = *pDefData++;
912 0 : if ( nAdjustmentDefaults > nAdjustmentValues )
913 : {
914 0 : seqAdjustmentValues.realloc( nAdjustmentDefaults );
915 0 : for ( i = nAdjustmentValues; i < nAdjustmentDefaults; i++ )
916 : {
917 0 : seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
918 0 : seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
919 : }
920 : }
921 : // check if there are defaulted adjustment values that should be filled the hard coded defaults (pDefValue)
922 0 : sal_Int32 nCount = nAdjustmentValues > nAdjustmentDefaults ? nAdjustmentDefaults : nAdjustmentValues;
923 0 : for ( i = 0; i < nCount; i++ )
924 : {
925 0 : if ( seqAdjustmentValues[ i ].State != com::sun::star::beans::PropertyState_DIRECT_VALUE )
926 : {
927 0 : seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
928 0 : seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
929 : }
930 : }
931 : }
932 0 : aPropVal.Name = sAdjustmentValues;
933 0 : aPropVal.Value <<= seqAdjustmentValues;
934 0 : aGeometryItem.SetPropertyValue( aPropVal );
935 :
936 :
937 : // Coordsize
938 :
939 0 : const OUString sViewBox( "ViewBox" );
940 0 : const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
941 0 : com::sun::star::awt::Rectangle aViewBox;
942 0 : if ( !pViewBox || !(*pViewBox >>= aViewBox ) )
943 : {
944 0 : if ( pDefCustomShape )
945 : {
946 0 : aViewBox.X = 0;
947 0 : aViewBox.Y = 0;
948 0 : aViewBox.Width = pDefCustomShape->nCoordWidth;
949 0 : aViewBox.Height= pDefCustomShape->nCoordHeight;
950 0 : aPropVal.Name = sViewBox;
951 0 : aPropVal.Value <<= aViewBox;
952 0 : aGeometryItem.SetPropertyValue( aPropVal );
953 : }
954 : }
955 :
956 0 : const OUString sPath( "Path" );
957 :
958 :
959 : // Path/Coordinates
960 :
961 0 : const OUString sCoordinates( "Coordinates" );
962 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
963 0 : if ( !pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
964 : {
965 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
966 :
967 0 : sal_Int32 i, nCount = pDefCustomShape->nVertices;
968 0 : seqCoordinates.realloc( nCount );
969 0 : for ( i = 0; i < nCount; i++ )
970 : {
971 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
972 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
973 : }
974 0 : aPropVal.Name = sCoordinates;
975 0 : aPropVal.Value <<= seqCoordinates;
976 0 : aGeometryItem.SetPropertyValue( sPath, aPropVal );
977 : }
978 :
979 : // Path/GluePoints
980 0 : const OUString sGluePoints( "GluePoints" );
981 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
982 0 : if ( !pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
983 : {
984 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints;
985 0 : sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
986 0 : seqGluePoints.realloc( nCount );
987 0 : for ( i = 0; i < nCount; i++ )
988 : {
989 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
990 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
991 : }
992 0 : aPropVal.Name = sGluePoints;
993 0 : aPropVal.Value <<= seqGluePoints;
994 0 : aGeometryItem.SetPropertyValue( sPath, aPropVal );
995 : }
996 :
997 : // Path/Segments
998 0 : const OUString sSegments( "Segments" );
999 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
1000 0 : if ( !pAny && pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
1001 : {
1002 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments;
1003 :
1004 0 : sal_Int32 i, nCount = pDefCustomShape->nElements;
1005 0 : seqSegments.realloc( nCount );
1006 0 : for ( i = 0; i < nCount; i++ )
1007 : {
1008 0 : EnhancedCustomShapeSegment& rSegInfo = seqSegments[ i ];
1009 0 : sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
1010 0 : lcl_ShapeSegmentFromBinary( rSegInfo, nSDat );
1011 : }
1012 0 : aPropVal.Name = sSegments;
1013 0 : aPropVal.Value <<= seqSegments;
1014 0 : aGeometryItem.SetPropertyValue( sPath, aPropVal );
1015 : }
1016 :
1017 : // Path/StretchX
1018 0 : const OUString sStretchX( "StretchX" );
1019 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
1020 0 : if ( !pAny && pDefCustomShape )
1021 : {
1022 0 : sal_Int32 nXRef = pDefCustomShape->nXRef;
1023 0 : if ( ( nXRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1024 : {
1025 0 : aPropVal.Name = sStretchX;
1026 0 : aPropVal.Value <<= nXRef;
1027 0 : aGeometryItem.SetPropertyValue( sPath, aPropVal );
1028 : }
1029 : }
1030 :
1031 : // Path/StretchY
1032 0 : const OUString sStretchY( "StretchY" );
1033 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
1034 0 : if ( !pAny && pDefCustomShape )
1035 : {
1036 0 : sal_Int32 nYRef = pDefCustomShape->nYRef;
1037 0 : if ( ( nYRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1038 : {
1039 0 : aPropVal.Name = sStretchY;
1040 0 : aPropVal.Value <<= nYRef;
1041 0 : aGeometryItem.SetPropertyValue( sPath, aPropVal );
1042 : }
1043 : }
1044 :
1045 : // Path/TextFrames
1046 0 : const OUString sTextFrames( "TextFrames" );
1047 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
1048 0 : if ( !pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
1049 : {
1050 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames;
1051 :
1052 0 : sal_Int32 i, nCount = pDefCustomShape->nTextRect;
1053 0 : seqTextFrames.realloc( nCount );
1054 0 : const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
1055 0 : for ( i = 0; i < nCount; i++, pRectangles++ )
1056 : {
1057 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.First, pRectangles->nPairA.nValA );
1058 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
1059 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.First, pRectangles->nPairB.nValA );
1060 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
1061 : }
1062 0 : aPropVal.Name = sTextFrames;
1063 0 : aPropVal.Value <<= seqTextFrames;
1064 0 : aGeometryItem.SetPropertyValue( sPath, aPropVal );
1065 : }
1066 :
1067 : // Equations
1068 0 : const OUString sEquations( "Equations" );
1069 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
1070 0 : if ( !pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
1071 : {
1072 0 : com::sun::star::uno::Sequence< OUString > seqEquations;
1073 :
1074 0 : sal_Int32 i, nCount = pDefCustomShape->nCalculation;
1075 0 : seqEquations.realloc( nCount );
1076 0 : const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
1077 0 : for ( i = 0; i < nCount; i++, pData++ )
1078 0 : seqEquations[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
1079 0 : aPropVal.Name = sEquations;
1080 0 : aPropVal.Value <<= seqEquations;
1081 0 : aGeometryItem.SetPropertyValue( aPropVal );
1082 : }
1083 :
1084 : // Handles
1085 0 : const OUString sHandles( "Handles" );
1086 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
1087 0 : if ( !pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
1088 : {
1089 0 : com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles;
1090 :
1091 0 : sal_Int32 i, nCount = pDefCustomShape->nHandles;
1092 0 : const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
1093 0 : seqHandles.realloc( nCount );
1094 0 : for ( i = 0; i < nCount; i++, pData++ )
1095 : {
1096 : sal_Int32 nPropertiesNeeded;
1097 0 : com::sun::star::beans::PropertyValues& rPropValues = seqHandles[ i ];
1098 0 : nPropertiesNeeded = GetNumberOfProperties( pData );
1099 0 : rPropValues.realloc( nPropertiesNeeded );
1100 0 : lcl_ShapePropertiesFromDFF( pData, rPropValues );
1101 : }
1102 0 : aPropVal.Name = sHandles;
1103 0 : aPropVal.Value <<= seqHandles;
1104 0 : aGeometryItem.SetPropertyValue( aPropVal );
1105 : }
1106 0 : SetMergedItem( aGeometryItem );
1107 0 : }
1108 :
1109 0 : bool SdrObjCustomShape::IsDefaultGeometry( const DefaultType eDefaultType ) const
1110 : {
1111 0 : bool bIsDefaultGeometry = false;
1112 :
1113 0 : PropertyValue aPropVal;
1114 0 : OUString sShapeType;
1115 0 : const OUString sType( "Type" );
1116 0 : SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1117 :
1118 0 : Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
1119 0 : if ( pAny )
1120 0 : *pAny >>= sShapeType;
1121 :
1122 0 : MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
1123 :
1124 0 : const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
1125 0 : const OUString sPath( "Path" );
1126 0 : switch( eDefaultType )
1127 : {
1128 : case DEFAULT_VIEWBOX :
1129 : {
1130 0 : const OUString sViewBox( "ViewBox" );
1131 0 : const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
1132 0 : com::sun::star::awt::Rectangle aViewBox;
1133 0 : if ( pViewBox && ( *pViewBox >>= aViewBox ) )
1134 : {
1135 0 : if ( ( aViewBox.Width == pDefCustomShape->nCoordWidth )
1136 0 : && ( aViewBox.Height == pDefCustomShape->nCoordHeight ) )
1137 0 : bIsDefaultGeometry = true;
1138 0 : }
1139 : }
1140 0 : break;
1141 :
1142 : case DEFAULT_PATH :
1143 : {
1144 0 : const OUString sCoordinates( "Coordinates" );
1145 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
1146 0 : if ( pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
1147 : {
1148 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2;
1149 0 : if ( *pAny >>= seqCoordinates1 )
1150 : {
1151 0 : sal_Int32 i, nCount = pDefCustomShape->nVertices;
1152 0 : seqCoordinates2.realloc( nCount );
1153 0 : for ( i = 0; i < nCount; i++ )
1154 : {
1155 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
1156 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
1157 : }
1158 0 : if ( seqCoordinates1 == seqCoordinates2 )
1159 0 : bIsDefaultGeometry = true;
1160 0 : }
1161 : }
1162 0 : else if ( pDefCustomShape && ( ( pDefCustomShape->nVertices == 0 ) || ( pDefCustomShape->pVertices == 0 ) ) )
1163 0 : bIsDefaultGeometry = true;
1164 : }
1165 0 : break;
1166 :
1167 : case DEFAULT_GLUEPOINTS :
1168 : {
1169 0 : const OUString sGluePoints( "GluePoints" );
1170 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
1171 0 : if ( pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
1172 : {
1173 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints1, seqGluePoints2;
1174 0 : if ( *pAny >>= seqGluePoints1 )
1175 : {
1176 0 : sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
1177 0 : seqGluePoints2.realloc( nCount );
1178 0 : for ( i = 0; i < nCount; i++ )
1179 : {
1180 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
1181 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
1182 : }
1183 0 : if ( seqGluePoints1 == seqGluePoints2 )
1184 0 : bIsDefaultGeometry = true;
1185 0 : }
1186 : }
1187 0 : else if ( pDefCustomShape && ( pDefCustomShape->nGluePoints == 0 ) )
1188 0 : bIsDefaultGeometry = true;
1189 : }
1190 0 : break;
1191 :
1192 : case DEFAULT_SEGMENTS :
1193 : {
1194 : // Path/Segments
1195 0 : const OUString sSegments( "Segments" );
1196 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
1197 0 : if ( pAny )
1198 : {
1199 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments1, seqSegments2;
1200 0 : if ( *pAny >>= seqSegments1 )
1201 : {
1202 0 : if ( pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
1203 : {
1204 0 : sal_Int32 i, nCount = pDefCustomShape->nElements;
1205 0 : if ( nCount )
1206 : {
1207 0 : seqSegments2.realloc( nCount );
1208 0 : for ( i = 0; i < nCount; i++ )
1209 : {
1210 0 : EnhancedCustomShapeSegment& rSegInfo = seqSegments2[ i ];
1211 0 : sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
1212 0 : lcl_ShapeSegmentFromBinary( rSegInfo, nSDat );
1213 : }
1214 0 : if ( seqSegments1 == seqSegments2 )
1215 0 : bIsDefaultGeometry = true;
1216 0 : }
1217 : }
1218 : else
1219 : {
1220 : // check if its the default segment description ( M L Z N )
1221 0 : if ( seqSegments1.getLength() == 4 )
1222 : {
1223 0 : if ( ( seqSegments1[ 0 ].Command == EnhancedCustomShapeSegmentCommand::MOVETO )
1224 0 : && ( seqSegments1[ 1 ].Command == EnhancedCustomShapeSegmentCommand::LINETO )
1225 0 : && ( seqSegments1[ 2 ].Command == EnhancedCustomShapeSegmentCommand::CLOSESUBPATH )
1226 0 : && ( seqSegments1[ 3 ].Command == EnhancedCustomShapeSegmentCommand::ENDSUBPATH ) )
1227 0 : bIsDefaultGeometry = true;
1228 : }
1229 : }
1230 0 : }
1231 : }
1232 0 : else if ( pDefCustomShape && ( ( pDefCustomShape->nElements == 0 ) || ( pDefCustomShape->pElements == 0 ) ) )
1233 0 : bIsDefaultGeometry = true;
1234 : }
1235 0 : break;
1236 :
1237 : case DEFAULT_STRETCHX :
1238 : {
1239 0 : const OUString sStretchX( "StretchX" );
1240 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
1241 0 : if ( pAny && pDefCustomShape )
1242 : {
1243 0 : sal_Int32 nStretchX = 0;
1244 0 : if ( *pAny >>= nStretchX )
1245 : {
1246 0 : if ( pDefCustomShape->nXRef == nStretchX )
1247 0 : bIsDefaultGeometry = true;
1248 0 : }
1249 : }
1250 0 : else if ( pDefCustomShape && ( pDefCustomShape->nXRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1251 0 : bIsDefaultGeometry = true;
1252 : }
1253 0 : break;
1254 :
1255 : case DEFAULT_STRETCHY :
1256 : {
1257 0 : const OUString sStretchY( "StretchY" );
1258 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
1259 0 : if ( pAny && pDefCustomShape )
1260 : {
1261 0 : sal_Int32 nStretchY = 0;
1262 0 : if ( *pAny >>= nStretchY )
1263 : {
1264 0 : if ( pDefCustomShape->nYRef == nStretchY )
1265 0 : bIsDefaultGeometry = true;
1266 0 : }
1267 : }
1268 0 : else if ( pDefCustomShape && ( pDefCustomShape->nYRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1269 0 : bIsDefaultGeometry = true;
1270 : }
1271 0 : break;
1272 :
1273 : case DEFAULT_EQUATIONS :
1274 : {
1275 0 : const OUString sEquations( "Equations" );
1276 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
1277 0 : if ( pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
1278 : {
1279 0 : com::sun::star::uno::Sequence< OUString > seqEquations1, seqEquations2;
1280 0 : if ( *pAny >>= seqEquations1 )
1281 : {
1282 0 : sal_Int32 i, nCount = pDefCustomShape->nCalculation;
1283 0 : seqEquations2.realloc( nCount );
1284 :
1285 0 : const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
1286 0 : for ( i = 0; i < nCount; i++, pData++ )
1287 0 : seqEquations2[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
1288 :
1289 0 : if ( seqEquations1 == seqEquations2 )
1290 0 : bIsDefaultGeometry = true;
1291 0 : }
1292 : }
1293 0 : else if ( pDefCustomShape && ( ( pDefCustomShape->nCalculation == 0 ) || ( pDefCustomShape->pCalculation == 0 ) ) )
1294 0 : bIsDefaultGeometry = true;
1295 : }
1296 0 : break;
1297 :
1298 : case DEFAULT_TEXTFRAMES :
1299 : {
1300 0 : const OUString sTextFrames( "TextFrames" );
1301 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
1302 0 : if ( pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
1303 : {
1304 0 : com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames1, seqTextFrames2;
1305 0 : if ( *pAny >>= seqTextFrames1 )
1306 : {
1307 0 : sal_Int32 i, nCount = pDefCustomShape->nTextRect;
1308 0 : seqTextFrames2.realloc( nCount );
1309 0 : const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
1310 0 : for ( i = 0; i < nCount; i++, pRectangles++ )
1311 : {
1312 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.First, pRectangles->nPairA.nValA );
1313 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
1314 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.First, pRectangles->nPairB.nValA );
1315 0 : EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
1316 : }
1317 0 : if ( seqTextFrames1 == seqTextFrames2 )
1318 0 : bIsDefaultGeometry = true;
1319 0 : }
1320 : }
1321 0 : else if ( pDefCustomShape && ( ( pDefCustomShape->nTextRect == 0 ) || ( pDefCustomShape->pTextRect == 0 ) ) )
1322 0 : bIsDefaultGeometry = true;
1323 : }
1324 0 : break;
1325 :
1326 : case DEFAULT_HANDLES :
1327 : {
1328 0 : const OUString sHandles( "Handles" );
1329 0 : pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
1330 0 : if ( pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
1331 : {
1332 0 : com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles1, seqHandles2;
1333 0 : if ( *pAny >>= seqHandles1 )
1334 : {
1335 0 : sal_Int32 i, nCount = pDefCustomShape->nHandles;
1336 0 : const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
1337 0 : seqHandles2.realloc( nCount );
1338 0 : for ( i = 0; i < nCount; i++, pData++ )
1339 : {
1340 : sal_Int32 nPropertiesNeeded;
1341 0 : com::sun::star::beans::PropertyValues& rPropValues = seqHandles2[ i ];
1342 0 : nPropertiesNeeded = GetNumberOfProperties( pData );
1343 0 : rPropValues.realloc( nPropertiesNeeded );
1344 0 : lcl_ShapePropertiesFromDFF( pData, rPropValues );
1345 : }
1346 0 : if ( seqHandles1 == seqHandles2 )
1347 0 : bIsDefaultGeometry = true;
1348 0 : }
1349 : }
1350 0 : else if ( pDefCustomShape && ( ( pDefCustomShape->nHandles == 0 ) || ( pDefCustomShape->pHandles == 0 ) ) )
1351 0 : bIsDefaultGeometry = true;
1352 : }
1353 0 : break;
1354 : }
1355 0 : return bIsDefaultGeometry;
1356 : }
1357 :
1358 0 : void SdrObjCustomShape::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1359 : {
1360 0 : rInfo.bResizeFreeAllowed=fObjectRotation == 0.0;
1361 0 : rInfo.bResizePropAllowed=true;
1362 0 : rInfo.bRotateFreeAllowed=true;
1363 0 : rInfo.bRotate90Allowed =true;
1364 0 : rInfo.bMirrorFreeAllowed=true;
1365 0 : rInfo.bMirror45Allowed =true;
1366 0 : rInfo.bMirror90Allowed =true;
1367 0 : rInfo.bTransparenceAllowed = false;
1368 0 : rInfo.bGradientAllowed = false;
1369 0 : rInfo.bShearAllowed =true;
1370 0 : rInfo.bEdgeRadiusAllowed=false;
1371 0 : rInfo.bNoContortion =true;
1372 :
1373 : // #i37011#
1374 0 : if ( mXRenderedCustomShape.is() )
1375 : {
1376 0 : const SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
1377 0 : if ( pRenderedCustomShape )
1378 : {
1379 : // #i37262#
1380 : // Iterate self over the contained objects, since there are combinations of
1381 : // polygon and curve objects. In that case, aInfo.bCanConvToPath and
1382 : // aInfo.bCanConvToPoly would be false. What is needed here is an or, not an and.
1383 0 : SdrObjListIter aIterator(*pRenderedCustomShape);
1384 0 : while(aIterator.IsMore())
1385 : {
1386 0 : SdrObject* pCandidate = aIterator.Next();
1387 0 : SdrObjTransformInfoRec aInfo;
1388 0 : pCandidate->TakeObjInfo(aInfo);
1389 :
1390 : // set path and poly conversion if one is possible since
1391 : // this object will first be broken
1392 0 : const bool bCanConvToPathOrPoly(aInfo.bCanConvToPath || aInfo.bCanConvToPoly);
1393 0 : if(rInfo.bCanConvToPath != bCanConvToPathOrPoly)
1394 : {
1395 0 : rInfo.bCanConvToPath = bCanConvToPathOrPoly;
1396 : }
1397 :
1398 0 : if(rInfo.bCanConvToPoly != bCanConvToPathOrPoly)
1399 : {
1400 0 : rInfo.bCanConvToPoly = bCanConvToPathOrPoly;
1401 : }
1402 :
1403 0 : if(rInfo.bCanConvToContour != aInfo.bCanConvToContour)
1404 : {
1405 0 : rInfo.bCanConvToContour = aInfo.bCanConvToContour;
1406 : }
1407 :
1408 0 : if(rInfo.bShearAllowed != aInfo.bShearAllowed)
1409 : {
1410 0 : rInfo.bShearAllowed = aInfo.bShearAllowed;
1411 : }
1412 0 : }
1413 : }
1414 : }
1415 0 : }
1416 :
1417 0 : void SdrObjCustomShape::SetModel(SdrModel* pNewModel)
1418 : {
1419 0 : SdrTextObj::SetModel(pNewModel);
1420 0 : mXRenderedCustomShape.clear();
1421 0 : }
1422 :
1423 0 : sal_uInt16 SdrObjCustomShape::GetObjIdentifier() const
1424 : {
1425 0 : return sal_uInt16(OBJ_CUSTOMSHAPE);
1426 : }
1427 :
1428 :
1429 :
1430 0 : void SdrObjCustomShape::RecalcSnapRect()
1431 : {
1432 0 : SdrTextObj::RecalcSnapRect();
1433 0 : }
1434 0 : const Rectangle& SdrObjCustomShape::GetSnapRect() const
1435 : {
1436 0 : return SdrTextObj::GetSnapRect();
1437 : }
1438 0 : const Rectangle& SdrObjCustomShape::GetCurrentBoundRect() const
1439 : {
1440 0 : return SdrTextObj::GetCurrentBoundRect();
1441 : }
1442 0 : const Rectangle& SdrObjCustomShape::GetLogicRect() const
1443 : {
1444 0 : return SdrTextObj::GetLogicRect();
1445 : }
1446 :
1447 : // #115391# This implementation is based on the TextFrame size of the CustomShape and the
1448 : // state of the ResizeShapeToFitText flag to correctly set TextMinFrameWidth/Height
1449 0 : void SdrObjCustomShape::AdaptTextMinSize()
1450 : {
1451 0 : if(!pModel || !pModel->IsPasteResize())
1452 : {
1453 0 : const bool bResizeShapeToFitText(static_cast< const SdrTextAutoGrowHeightItem& >(GetObjectItem(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue());
1454 : SfxItemSet aSet(
1455 0 : *GetObjectItemSet().GetPool(),
1456 : SDRATTR_TEXT_MINFRAMEHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
1457 : SDRATTR_TEXT_MINFRAMEWIDTH, SDRATTR_TEXT_AUTOGROWWIDTH, // contains SDRATTR_TEXT_MAXFRAMEWIDTH
1458 0 : 0, 0);
1459 0 : bool bChanged(false);
1460 :
1461 0 : if(bResizeShapeToFitText)
1462 : {
1463 : // always reset MinWidthHeight to zero to only rely on text size and frame size
1464 : // to allow resizing being completely dependent on text size only
1465 0 : aSet.Put(SdrTextMinFrameWidthItem(0));
1466 0 : aSet.Put(SdrTextMinFrameHeightItem(0));
1467 0 : bChanged = true;
1468 : }
1469 : else
1470 : {
1471 : // recreate from CustomShape-specific TextBounds
1472 0 : Rectangle aTextBound(aRect);
1473 :
1474 0 : if(GetTextBounds(aTextBound))
1475 : {
1476 0 : const long nHDist(GetTextLeftDistance() + GetTextRightDistance());
1477 0 : const long nVDist(GetTextUpperDistance() + GetTextLowerDistance());
1478 0 : const long nTWdt(std::max(long(0), (long)(aTextBound.GetWidth() - 1 - nHDist)));
1479 0 : const long nTHgt(std::max(long(0), (long)(aTextBound.GetHeight() - 1 - nVDist)));
1480 :
1481 0 : aSet.Put(SdrTextMinFrameWidthItem(nTWdt));
1482 0 : aSet.Put(SdrTextMinFrameHeightItem(nTHgt));
1483 0 : bChanged = true;
1484 : }
1485 : }
1486 :
1487 0 : if(bChanged)
1488 : {
1489 0 : SetObjectItemSet(aSet);
1490 0 : NbcAdjustTextFrameWidthAndHeight();
1491 0 : }
1492 : }
1493 0 : }
1494 :
1495 0 : void SdrObjCustomShape::NbcSetSnapRect( const Rectangle& rRect )
1496 : {
1497 0 : aRect=rRect;
1498 0 : ImpJustifyRect(aRect);
1499 0 : InvalidateRenderGeometry();
1500 :
1501 : // #115391#
1502 0 : AdaptTextMinSize();
1503 :
1504 0 : ImpCheckShear();
1505 0 : SetRectsDirty();
1506 0 : SetChanged();
1507 0 : }
1508 0 : void SdrObjCustomShape::SetSnapRect( const Rectangle& rRect )
1509 : {
1510 0 : Rectangle aBoundRect0;
1511 0 : if ( pUserCall )
1512 0 : aBoundRect0 = GetLastBoundRect();
1513 0 : NbcSetSnapRect( rRect );
1514 0 : BroadcastObjectChange();
1515 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1516 0 : }
1517 0 : void SdrObjCustomShape::NbcSetLogicRect( const Rectangle& rRect )
1518 : {
1519 0 : aRect = rRect;
1520 0 : ImpJustifyRect( aRect );
1521 0 : InvalidateRenderGeometry();
1522 :
1523 : // #115391#
1524 0 : AdaptTextMinSize();
1525 :
1526 0 : SetRectsDirty();
1527 0 : SetChanged();
1528 0 : }
1529 0 : void SdrObjCustomShape::SetLogicRect( const Rectangle& rRect )
1530 : {
1531 0 : Rectangle aBoundRect0;
1532 0 : if ( pUserCall )
1533 0 : aBoundRect0 = GetLastBoundRect();
1534 0 : NbcSetLogicRect(rRect);
1535 0 : BroadcastObjectChange();
1536 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1537 0 : }
1538 0 : void SdrObjCustomShape::Move( const Size& rSiz )
1539 : {
1540 0 : if ( rSiz.Width() || rSiz.Height() )
1541 : {
1542 0 : Rectangle aBoundRect0;
1543 0 : if ( pUserCall )
1544 0 : aBoundRect0 = GetLastBoundRect();
1545 0 : NbcMove(rSiz);
1546 0 : SetChanged();
1547 0 : BroadcastObjectChange();
1548 0 : SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1549 : }
1550 0 : }
1551 0 : void SdrObjCustomShape::NbcMove( const Size& rSiz )
1552 : {
1553 0 : SdrTextObj::NbcMove( rSiz );
1554 0 : if ( mXRenderedCustomShape.is() )
1555 : {
1556 0 : SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
1557 0 : if ( pRenderedCustomShape )
1558 : {
1559 : // #i97149# the visualisation shape needs to be informed
1560 : // about change, too
1561 0 : pRenderedCustomShape->ActionChanged();
1562 0 : pRenderedCustomShape->NbcMove( rSiz );
1563 : }
1564 : }
1565 :
1566 : // #i37011# adapt geometry shadow
1567 0 : if(mpLastShadowGeometry)
1568 : {
1569 0 : mpLastShadowGeometry->NbcMove( rSiz );
1570 : }
1571 0 : }
1572 0 : void SdrObjCustomShape::Resize( const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative )
1573 : {
1574 0 : SdrTextObj::Resize( rRef, xFact, yFact, bUnsetRelative );
1575 0 : }
1576 :
1577 0 : void SdrObjCustomShape::NbcResize( const Point& rRef, const Fraction& rxFact, const Fraction& ryFact )
1578 : {
1579 0 : Fraction xFact( rxFact );
1580 0 : Fraction yFact( ryFact );
1581 :
1582 : // taking care of handles that should not been changed
1583 0 : Rectangle aOld( aRect );
1584 0 : std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
1585 :
1586 0 : SdrTextObj::NbcResize( rRef, xFact, yFact );
1587 :
1588 0 : if ( ( xFact.GetNumerator() != xFact.GetDenominator() )
1589 0 : || ( yFact.GetNumerator()!= yFact.GetDenominator() ) )
1590 : {
1591 0 : if ( ( ( xFact.GetNumerator() < 0 ) && ( xFact.GetDenominator() > 0 ) ) ||
1592 0 : ( ( xFact.GetNumerator() > 0 ) && ( xFact.GetDenominator() < 0 ) ) )
1593 : {
1594 0 : SetMirroredX( IsMirroredX() == false );
1595 : }
1596 0 : if ( ( ( yFact.GetNumerator() < 0 ) && ( yFact.GetDenominator() > 0 ) ) ||
1597 0 : ( ( yFact.GetNumerator() > 0 ) && ( yFact.GetDenominator() < 0 ) ) )
1598 : {
1599 0 : SetMirroredY( IsMirroredY() == false );
1600 : }
1601 : }
1602 :
1603 0 : for (std::vector< SdrCustomShapeInteraction >::const_iterator aIter( aInteractionHandles.begin() ), aEnd( aInteractionHandles.end() );
1604 : aIter != aEnd; ++aIter )
1605 : {
1606 : try
1607 : {
1608 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
1609 0 : aIter->xInteraction->setControllerPosition( aIter->aPosition );
1610 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
1611 : {
1612 0 : sal_Int32 nX = ( aIter->aPosition.X - aOld.Left() ) + aRect.Left();
1613 0 : aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
1614 : }
1615 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
1616 : {
1617 0 : sal_Int32 nY = ( aIter->aPosition.Y - aOld.Top() ) + aRect.Top();
1618 0 : aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
1619 : }
1620 : }
1621 0 : catch ( const uno::RuntimeException& )
1622 : {
1623 : }
1624 : }
1625 0 : InvalidateRenderGeometry();
1626 0 : }
1627 0 : void SdrObjCustomShape::NbcRotate( const Point& rRef, long nWink, double sn, double cs )
1628 : {
1629 0 : bool bMirroredX = IsMirroredX();
1630 0 : bool bMirroredY = IsMirroredY();
1631 :
1632 0 : fObjectRotation = fmod( fObjectRotation, 360.0 );
1633 0 : if ( fObjectRotation < 0 )
1634 0 : fObjectRotation = 360 + fObjectRotation;
1635 :
1636 : // the rotation angle for ashapes is stored in fObjectRotation, this rotation
1637 : // has to be applied to the text object (which is internally using aGeo.nWink).
1638 0 : SdrTextObj::NbcRotate( aRect.TopLeft(), -aGeo.nDrehWink, // retrieving the unrotated text object
1639 : sin( (-aGeo.nDrehWink) * F_PI18000 ),
1640 0 : cos( (-aGeo.nDrehWink) * F_PI18000 ) );
1641 0 : aGeo.nDrehWink = 0; // resetting aGeo data
1642 0 : aGeo.RecalcSinCos();
1643 :
1644 0 : long nW = (long)( fObjectRotation * 100 ); // applying our object rotation
1645 0 : if ( bMirroredX )
1646 0 : nW = 36000 - nW;
1647 0 : if ( bMirroredY )
1648 0 : nW = 18000 - nW;
1649 0 : nW = nW % 36000;
1650 0 : if ( nW < 0 )
1651 0 : nW = 36000 + nW;
1652 0 : SdrTextObj::NbcRotate( aRect.TopLeft(), nW, // applying text rotation
1653 : sin( nW * F_PI18000 ),
1654 0 : cos( nW * F_PI18000 ) );
1655 :
1656 0 : int nSwap = 0;
1657 0 : if ( bMirroredX )
1658 0 : nSwap ^= 1;
1659 0 : if ( bMirroredY )
1660 0 : nSwap ^= 1;
1661 :
1662 0 : double fWink = nWink; // updating to our new object rotation
1663 0 : fWink /= 100.0;
1664 0 : fObjectRotation = fmod( nSwap ? fObjectRotation - fWink : fObjectRotation + fWink, 360.0 );
1665 0 : if ( fObjectRotation < 0 )
1666 0 : fObjectRotation = 360 + fObjectRotation;
1667 :
1668 0 : SdrTextObj::NbcRotate( rRef, nWink, sn, cs ); // applying text rotation
1669 0 : InvalidateRenderGeometry();
1670 0 : }
1671 :
1672 0 : void SdrObjCustomShape::NbcMirror( const Point& rRef1, const Point& rRef2 )
1673 : {
1674 : // TTTT: Fix for old mirroring, can be removed again in aw080
1675 : // storing horizontal and vertical flipping without modifying the rotate angle
1676 : // decompose other flipping to rotation and MirrorX.
1677 0 : long ndx = rRef2.X()-rRef1.X();
1678 0 : long ndy = rRef2.Y()-rRef1.Y();
1679 :
1680 0 : if(!ndx) // MirroredX
1681 : {
1682 0 : SetMirroredX(!IsMirroredX());
1683 0 : SdrTextObj::NbcMirror( rRef1, rRef2 );
1684 : }
1685 : else
1686 : {
1687 0 : if(!ndy) // MirroredY
1688 : {
1689 0 : SetMirroredY(!IsMirroredY());
1690 0 : SdrTextObj::NbcMirror( rRef1, rRef2 );
1691 : }
1692 : else // neither horizontal nor vertical
1693 : {
1694 0 : SetMirroredX(!IsMirroredX());
1695 :
1696 : // call parent
1697 0 : SdrTextObj::NbcMirror( rRef1, rRef2 );
1698 :
1699 : // update fObjectRotation
1700 0 : long nTextObjRotation = aGeo.nDrehWink;
1701 0 : double fWink = nTextObjRotation;
1702 :
1703 0 : fWink /= 100.0;
1704 :
1705 0 : bool bSingleFlip = (IsMirroredX()!= IsMirroredY());
1706 :
1707 0 : fObjectRotation = fmod( bSingleFlip ? -fWink : fWink, 360.0 );
1708 :
1709 0 : if ( fObjectRotation < 0 )
1710 : {
1711 0 : fObjectRotation = 360.0 + fObjectRotation;
1712 : }
1713 : }
1714 : }
1715 :
1716 0 : InvalidateRenderGeometry();
1717 0 : }
1718 :
1719 0 : void SdrObjCustomShape::Shear( const Point& rRef, long nWink, double tn, bool bVShear )
1720 : {
1721 0 : SdrTextObj::Shear( rRef, nWink, tn, bVShear );
1722 0 : InvalidateRenderGeometry();
1723 0 : }
1724 0 : void SdrObjCustomShape::NbcShear( const Point& rRef, long nWink, double tn, bool bVShear )
1725 : {
1726 : // TTTT: Fix for old mirroring, can be removed again in aw080
1727 0 : SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
1728 :
1729 : // updating fObjectRotation
1730 0 : long nTextObjRotation = aGeo.nDrehWink;
1731 0 : double fWink = nTextObjRotation;
1732 :
1733 0 : fWink /= 100.0;
1734 :
1735 0 : bool bSingleFlip = (IsMirroredX()!= IsMirroredY());
1736 :
1737 0 : fObjectRotation = fmod( bSingleFlip ? -fWink : fWink, 360.0 );
1738 :
1739 0 : if ( fObjectRotation < 0 )
1740 : {
1741 0 : fObjectRotation = 360.0 + fObjectRotation;
1742 : }
1743 :
1744 0 : InvalidateRenderGeometry();
1745 0 : }
1746 :
1747 :
1748 :
1749 0 : SdrGluePoint SdrObjCustomShape::GetVertexGluePoint(sal_uInt16 nPosNum) const
1750 : {
1751 0 : sal_Int32 nWdt = ImpGetLineWdt(); // #i25616#
1752 :
1753 : // #i25616#
1754 0 : if(!LineIsOutsideGeometry())
1755 : {
1756 0 : nWdt++;
1757 0 : nWdt /= 2;
1758 : }
1759 :
1760 0 : Point aPt;
1761 0 : switch (nPosNum) {
1762 0 : case 0: aPt=aRect.TopCenter(); aPt.Y()-=nWdt; break;
1763 0 : case 1: aPt=aRect.RightCenter(); aPt.X()+=nWdt; break;
1764 0 : case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break;
1765 0 : case 3: aPt=aRect.LeftCenter(); aPt.X()-=nWdt; break;
1766 : }
1767 0 : if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
1768 0 : if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1769 0 : aPt-=GetSnapRect().Center();
1770 0 : SdrGluePoint aGP(aPt);
1771 0 : aGP.SetPercent(false);
1772 0 : return aGP;
1773 : }
1774 :
1775 :
1776 :
1777 : // #i38892#
1778 0 : void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded()
1779 : {
1780 0 : const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
1781 :
1782 0 : if(pSdrObject)
1783 : {
1784 0 : const SdrGluePointList* pSource = pSdrObject->GetGluePointList();
1785 :
1786 0 : if(pSource && pSource->GetCount())
1787 : {
1788 0 : if(!SdrTextObj::GetGluePointList())
1789 : {
1790 0 : SdrTextObj::ForceGluePointList();
1791 : }
1792 :
1793 0 : const SdrGluePointList* pList = SdrTextObj::GetGluePointList();
1794 :
1795 0 : if(pList)
1796 : {
1797 0 : SdrGluePointList aNewList;
1798 : sal_uInt16 a;
1799 :
1800 0 : for(a = 0; a < pSource->GetCount(); a++)
1801 : {
1802 0 : SdrGluePoint aCopy((*pSource)[a]);
1803 0 : aCopy.SetUserDefined(false);
1804 0 : aNewList.Insert(aCopy);
1805 : }
1806 :
1807 0 : bool bMirroredX = IsMirroredX();
1808 0 : bool bMirroredY = IsMirroredY();
1809 :
1810 0 : long nShearWink = aGeo.nShearWink;
1811 0 : double fTan = aGeo.nTan;
1812 :
1813 0 : if ( aGeo.nDrehWink || nShearWink || bMirroredX || bMirroredY )
1814 : {
1815 0 : Polygon aPoly( aRect );
1816 0 : if( nShearWink )
1817 : {
1818 0 : sal_uInt16 nPointCount=aPoly.GetSize();
1819 0 : for (sal_uInt16 i=0; i<nPointCount; i++)
1820 0 : ShearPoint(aPoly[i],aRect.Center(), fTan, false );
1821 : }
1822 0 : if ( aGeo.nDrehWink )
1823 0 : aPoly.Rotate( aRect.Center(), aGeo.nDrehWink / 10 );
1824 :
1825 0 : Rectangle aBoundRect( aPoly.GetBoundRect() );
1826 0 : sal_Int32 nXDiff = aBoundRect.Left() - aRect.Left();
1827 0 : sal_Int32 nYDiff = aBoundRect.Top() - aRect.Top();
1828 :
1829 0 : if (nShearWink&&((bMirroredX&&!bMirroredY)||(bMirroredY&&!bMirroredX)))
1830 : {
1831 0 : nShearWink = -nShearWink;
1832 0 : fTan = -fTan;
1833 : }
1834 :
1835 0 : Point aRef( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
1836 0 : for ( a = 0; a < aNewList.GetCount(); a++ )
1837 : {
1838 0 : SdrGluePoint& rPoint = aNewList[ a ];
1839 0 : Point aGlue( rPoint.GetPos() );
1840 0 : if ( nShearWink )
1841 0 : ShearPoint( aGlue, aRef, fTan );
1842 :
1843 0 : RotatePoint( aGlue, aRef, sin( fObjectRotation * F_PI180 ), cos( fObjectRotation * F_PI180 ) );
1844 0 : if ( bMirroredX )
1845 0 : aGlue.X() = aRect.GetWidth() - aGlue.X();
1846 0 : if ( bMirroredY )
1847 0 : aGlue.Y() = aRect.GetHeight() - aGlue.Y();
1848 0 : aGlue.X() -= nXDiff;
1849 0 : aGlue.Y() -= nYDiff;
1850 0 : rPoint.SetPos( aGlue );
1851 0 : }
1852 : }
1853 :
1854 0 : for(a = 0; a < pList->GetCount(); a++)
1855 : {
1856 0 : const SdrGluePoint& rCandidate = (*pList)[a];
1857 :
1858 0 : if(rCandidate.IsUserDefined())
1859 : {
1860 0 : aNewList.Insert(rCandidate);
1861 : }
1862 : }
1863 :
1864 : // copy new list to local. This is NOT very convenient behavior, the local
1865 : // GluePointList should not be set, but we delivered by using GetGluePointList(),
1866 : // maybe on demand. Since the local object is changed here, this is assumed to
1867 : // be a result of GetGluePointList and thus the list is copied
1868 0 : if(pPlusData)
1869 : {
1870 0 : pPlusData->SetGluePoints(aNewList);
1871 0 : }
1872 : }
1873 : }
1874 : }
1875 0 : }
1876 :
1877 : // #i38892#
1878 0 : const SdrGluePointList* SdrObjCustomShape::GetGluePointList() const
1879 : {
1880 0 : ((SdrObjCustomShape*)this)->ImpCheckCustomGluePointsAreAdded();
1881 0 : return SdrTextObj::GetGluePointList();
1882 : }
1883 :
1884 : // #i38892#
1885 0 : SdrGluePointList* SdrObjCustomShape::ForceGluePointList()
1886 : {
1887 0 : if(SdrTextObj::ForceGluePointList())
1888 : {
1889 0 : ImpCheckCustomGluePointsAreAdded();
1890 0 : return SdrTextObj::ForceGluePointList();
1891 : }
1892 : else
1893 : {
1894 0 : return 0L;
1895 : }
1896 : }
1897 :
1898 :
1899 :
1900 0 : sal_uInt32 SdrObjCustomShape::GetHdlCount() const
1901 : {
1902 0 : const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
1903 0 : std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
1904 0 : return ( aInteractionHandles.size() + nBasicHdlCount );
1905 : }
1906 :
1907 0 : SdrHdl* SdrObjCustomShape::GetHdl( sal_uInt32 nHdlNum ) const
1908 : {
1909 0 : SdrHdl* pH = NULL;
1910 0 : const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
1911 :
1912 0 : if ( nHdlNum < nBasicHdlCount )
1913 0 : pH = SdrTextObj::GetHdl( nHdlNum );
1914 : else
1915 : {
1916 0 : std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
1917 0 : const sal_uInt32 nCustomShapeHdlNum(nHdlNum - nBasicHdlCount);
1918 :
1919 0 : if ( nCustomShapeHdlNum < aInteractionHandles.size() )
1920 : {
1921 0 : if ( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction.is() )
1922 : {
1923 : try
1924 : {
1925 0 : com::sun::star::awt::Point aPosition( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction->getPosition() );
1926 0 : pH = new SdrHdl( Point( aPosition.X, aPosition.Y ), HDL_CUSTOMSHAPE1 );
1927 0 : pH->SetPointNum( nCustomShapeHdlNum );
1928 0 : pH->SetObj( (SdrObject*)this );
1929 : }
1930 0 : catch ( const uno::RuntimeException& )
1931 : {
1932 : }
1933 : }
1934 0 : }
1935 : }
1936 0 : return pH;
1937 : }
1938 :
1939 :
1940 :
1941 0 : bool SdrObjCustomShape::hasSpecialDrag() const
1942 : {
1943 0 : return true;
1944 : }
1945 :
1946 0 : bool SdrObjCustomShape::beginSpecialDrag(SdrDragStat& rDrag) const
1947 : {
1948 0 : const SdrHdl* pHdl = rDrag.GetHdl();
1949 :
1950 0 : if(pHdl && HDL_CUSTOMSHAPE1 == pHdl->GetKind())
1951 : {
1952 0 : rDrag.SetEndDragChangesAttributes(true);
1953 0 : rDrag.SetNoSnap(true);
1954 : }
1955 : else
1956 : {
1957 0 : const SdrHdl* pHdl2 = rDrag.GetHdl();
1958 0 : const SdrHdlKind eHdl((pHdl2 == NULL) ? HDL_MOVE : pHdl2->GetKind());
1959 :
1960 0 : switch( eHdl )
1961 : {
1962 : case HDL_UPLFT :
1963 : case HDL_UPPER :
1964 : case HDL_UPRGT :
1965 : case HDL_LEFT :
1966 : case HDL_RIGHT :
1967 : case HDL_LWLFT :
1968 : case HDL_LOWER :
1969 : case HDL_LWRGT :
1970 : case HDL_MOVE :
1971 : {
1972 0 : break;
1973 : }
1974 : default:
1975 : {
1976 0 : return false;
1977 : }
1978 : }
1979 : }
1980 :
1981 0 : return true;
1982 : }
1983 :
1984 0 : void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObjCustomShape* pObj ) const
1985 : {
1986 0 : Rectangle aOld( pObj->aRect );
1987 0 : bool bOldMirroredX( pObj->IsMirroredX() );
1988 0 : bool bOldMirroredY( pObj->IsMirroredY() );
1989 :
1990 0 : Rectangle aNewRect( rNewRect );
1991 0 : aNewRect.Justify();
1992 :
1993 0 : std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
1994 :
1995 0 : GeoStat aGeoStat( pObj->GetGeoStat() );
1996 0 : if ( aNewRect.TopLeft()!= pObj->aRect.TopLeft() &&
1997 0 : ( pObj->aGeo.nDrehWink || pObj->aGeo.nShearWink ) )
1998 : {
1999 0 : Point aNewPos( aNewRect.TopLeft() );
2000 0 : if ( pObj->aGeo.nShearWink ) ShearPoint( aNewPos, aOld.TopLeft(), aGeoStat.nTan );
2001 0 : if ( pObj->aGeo.nDrehWink ) RotatePoint(aNewPos, aOld.TopLeft(), aGeoStat.nSin, aGeoStat.nCos );
2002 0 : aNewRect.SetPos( aNewPos );
2003 : }
2004 0 : if ( aNewRect != pObj->aRect )
2005 : {
2006 0 : pObj->SetLogicRect( aNewRect );
2007 0 : pObj->InvalidateRenderGeometry();
2008 :
2009 0 : if ( rNewRect.Left() > rNewRect.Right() )
2010 : {
2011 0 : Point aTop( ( pObj->GetSnapRect().Left() + pObj->GetSnapRect().Right() ) >> 1, pObj->GetSnapRect().Top() );
2012 0 : Point aBottom( aTop.X(), aTop.Y() + 1000 );
2013 0 : pObj->NbcMirror( aTop, aBottom );
2014 : }
2015 0 : if ( rNewRect.Top() > rNewRect.Bottom() )
2016 : {
2017 0 : Point aLeft( pObj->GetSnapRect().Left(), ( pObj->GetSnapRect().Top() + pObj->GetSnapRect().Bottom() ) >> 1 );
2018 0 : Point aRight( aLeft.X() + 1000, aLeft.Y() );
2019 0 : pObj->NbcMirror( aLeft, aRight );
2020 : }
2021 :
2022 0 : for (std::vector< SdrCustomShapeInteraction >::const_iterator aIter( aInteractionHandles.begin() ), aEnd( aInteractionHandles.end() );
2023 : aIter != aEnd ; ++aIter )
2024 : {
2025 : try
2026 : {
2027 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2028 0 : aIter->xInteraction->setControllerPosition( aIter->aPosition );
2029 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
2030 : {
2031 : sal_Int32 nX;
2032 0 : if ( bOldMirroredX )
2033 : {
2034 0 : nX = ( aIter->aPosition.X - aOld.Right() );
2035 0 : if ( rNewRect.Left() > rNewRect.Right() )
2036 0 : nX = pObj->aRect.Left() - nX;
2037 : else
2038 0 : nX += pObj->aRect.Right();
2039 : }
2040 : else
2041 : {
2042 0 : nX = ( aIter->aPosition.X - aOld.Left() );
2043 0 : if ( rNewRect.Left() > rNewRect.Right() )
2044 0 : nX = pObj->aRect.Right() - nX;
2045 : else
2046 0 : nX += pObj->aRect.Left();
2047 : }
2048 0 : aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
2049 : }
2050 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
2051 : {
2052 : sal_Int32 nY;
2053 0 : if ( bOldMirroredY )
2054 : {
2055 0 : nY = ( aIter->aPosition.Y - aOld.Bottom() );
2056 0 : if ( rNewRect.Top() > rNewRect.Bottom() )
2057 0 : nY = pObj->aRect.Top() - nY;
2058 : else
2059 0 : nY += pObj->aRect.Bottom();
2060 : }
2061 : else
2062 : {
2063 0 : nY = ( aIter->aPosition.Y - aOld.Top() );
2064 0 : if ( rNewRect.Top() > rNewRect.Bottom() )
2065 0 : nY = pObj->aRect.Bottom() - nY;
2066 : else
2067 0 : nY += pObj->aRect.Top();
2068 : }
2069 0 : aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
2070 : }
2071 : }
2072 0 : catch ( const uno::RuntimeException& )
2073 : {
2074 : }
2075 : }
2076 0 : }
2077 0 : }
2078 :
2079 0 : void SdrObjCustomShape::DragMoveCustomShapeHdl( const Point aDestination, const sal_uInt16 nCustomShapeHdlNum, SdrObjCustomShape* pObj ) const
2080 : {
2081 0 : std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
2082 0 : if ( nCustomShapeHdlNum < aInteractionHandles.size() )
2083 : {
2084 0 : SdrCustomShapeInteraction aInteractionHandle( aInteractionHandles[ nCustomShapeHdlNum ] );
2085 0 : if ( aInteractionHandle.xInteraction.is() )
2086 : {
2087 : try
2088 : {
2089 0 : com::sun::star::awt::Point aPt( aDestination.X(), aDestination.Y() );
2090 0 : if ( aInteractionHandle.nMode & CUSTOMSHAPE_HANDLE_MOVE_SHAPE )
2091 : {
2092 0 : sal_Int32 nXDiff = aPt.X - aInteractionHandle.aPosition.X;
2093 0 : sal_Int32 nYDiff = aPt.Y - aInteractionHandle.aPosition.Y;
2094 :
2095 0 : pObj->aRect.Move( nXDiff, nYDiff );
2096 0 : pObj->aOutRect.Move( nXDiff, nYDiff );
2097 0 : pObj->maSnapRect.Move( nXDiff, nYDiff );
2098 0 : pObj->SetRectsDirty(true);
2099 0 : pObj->InvalidateRenderGeometry();
2100 :
2101 0 : for (std::vector< SdrCustomShapeInteraction >::const_iterator aIter( aInteractionHandles.begin() ), aEnd( aInteractionHandles.end() ) ;
2102 : aIter != aEnd; ++aIter)
2103 : {
2104 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2105 : {
2106 0 : if ( aIter->xInteraction.is() )
2107 0 : aIter->xInteraction->setControllerPosition( aIter->aPosition );
2108 : }
2109 : }
2110 : }
2111 0 : aInteractionHandle.xInteraction->setControllerPosition( aPt );
2112 : }
2113 0 : catch ( const uno::RuntimeException& )
2114 : {
2115 : }
2116 0 : }
2117 0 : }
2118 0 : }
2119 :
2120 0 : bool SdrObjCustomShape::applySpecialDrag(SdrDragStat& rDrag)
2121 : {
2122 0 : const SdrHdl* pHdl = rDrag.GetHdl();
2123 0 : const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2124 :
2125 0 : switch(eHdl)
2126 : {
2127 : case HDL_CUSTOMSHAPE1 :
2128 : {
2129 0 : rDrag.SetEndDragChangesGeoAndAttributes(true);
2130 0 : DragMoveCustomShapeHdl( rDrag.GetNow(), (sal_uInt16)pHdl->GetPointNum(), this );
2131 0 : SetRectsDirty();
2132 0 : InvalidateRenderGeometry();
2133 0 : SetChanged();
2134 0 : break;
2135 : }
2136 :
2137 : case HDL_UPLFT :
2138 : case HDL_UPPER :
2139 : case HDL_UPRGT :
2140 : case HDL_LEFT :
2141 : case HDL_RIGHT :
2142 : case HDL_LWLFT :
2143 : case HDL_LOWER :
2144 : case HDL_LWRGT :
2145 : {
2146 0 : DragResizeCustomShape(ImpDragCalcRect(rDrag), this);
2147 0 : break;
2148 : }
2149 : case HDL_MOVE :
2150 : {
2151 0 : Move(Size(rDrag.GetDX(), rDrag.GetDY()));
2152 0 : break;
2153 : }
2154 0 : default: break;
2155 : }
2156 :
2157 0 : return true;
2158 : }
2159 :
2160 :
2161 :
2162 0 : void SdrObjCustomShape::DragCreateObject( SdrDragStat& rStat )
2163 : {
2164 0 : Rectangle aRect1;
2165 0 : rStat.TakeCreateRect( aRect1 );
2166 :
2167 0 : std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2168 :
2169 0 : sal_uInt32 nDefaultObjectSizeWidth = 3000; // default width from SDOptions ?
2170 0 : sal_uInt32 nDefaultObjectSizeHeight= 3000;
2171 :
2172 0 : if ( ImpVerticalSwitch( *this ) )
2173 : {
2174 0 : SetMirroredX( aRect1.Left() > aRect1.Right() );
2175 :
2176 0 : aRect1 = Rectangle( rStat.GetNow(), Size( nDefaultObjectSizeWidth, nDefaultObjectSizeHeight ) );
2177 : // subtracting the horizontal difference of the latest handle from shape position
2178 0 : if ( !aInteractionHandles.empty() )
2179 : {
2180 0 : sal_Int32 nHandlePos = aInteractionHandles[ aInteractionHandles.size() - 1 ].xInteraction->getPosition().X;
2181 0 : aRect1.Move( aRect.Left() - nHandlePos, 0 );
2182 : }
2183 : }
2184 0 : ImpJustifyRect( aRect1 );
2185 0 : rStat.SetActionRect( aRect1 );
2186 0 : aRect = aRect1;
2187 0 : SetRectsDirty();
2188 :
2189 0 : for (std::vector< SdrCustomShapeInteraction >::const_iterator aIter( aInteractionHandles.begin() ), aEnd( aInteractionHandles.end() );
2190 : aIter != aEnd ; ++aIter)
2191 : {
2192 : try
2193 : {
2194 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_CREATE_FIXED )
2195 0 : aIter->xInteraction->setControllerPosition( awt::Point( rStat.GetStart().X(), rStat.GetStart().Y() ) );
2196 : }
2197 0 : catch ( const uno::RuntimeException& )
2198 : {
2199 : }
2200 : }
2201 :
2202 0 : SetBoundRectDirty();
2203 0 : bSnapRectDirty=true;
2204 0 : }
2205 :
2206 0 : bool SdrObjCustomShape::BegCreate( SdrDragStat& rDrag )
2207 : {
2208 0 : return SdrTextObj::BegCreate( rDrag );
2209 : }
2210 :
2211 0 : bool SdrObjCustomShape::MovCreate(SdrDragStat& rStat)
2212 : {
2213 0 : SdrView* pView = rStat.GetView(); // #i37448#
2214 0 : if( pView && pView->IsSolidDragging() )
2215 : {
2216 0 : InvalidateRenderGeometry();
2217 : }
2218 0 : DragCreateObject( rStat );
2219 0 : SetRectsDirty();
2220 0 : return true;
2221 : }
2222 :
2223 0 : bool SdrObjCustomShape::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
2224 : {
2225 0 : DragCreateObject( rStat );
2226 :
2227 : // #115391#
2228 0 : AdaptTextMinSize();
2229 :
2230 0 : SetRectsDirty();
2231 0 : return ( eCmd == SDRCREATE_FORCEEND || rStat.GetPointAnz() >= 2 );
2232 : }
2233 :
2234 0 : basegfx::B2DPolyPolygon SdrObjCustomShape::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
2235 : {
2236 0 : return GetLineGeometry( this, false );
2237 : }
2238 :
2239 :
2240 :
2241 : // in context with the SdrObjCustomShape the SdrTextAutoGrowHeightItem == true -> Resize Shape to fit text,
2242 : // the SdrTextAutoGrowWidthItem == true -> Word wrap text in Shape
2243 0 : bool SdrObjCustomShape::IsAutoGrowHeight() const
2244 : {
2245 0 : const SfxItemSet& rSet = GetMergedItemSet();
2246 0 : bool bIsAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
2247 0 : if ( bIsAutoGrowHeight && IsVerticalWriting() )
2248 0 : bIsAutoGrowHeight = !((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue();
2249 0 : return bIsAutoGrowHeight;
2250 : }
2251 0 : bool SdrObjCustomShape::IsAutoGrowWidth() const
2252 : {
2253 0 : const SfxItemSet& rSet = GetMergedItemSet();
2254 0 : bool bIsAutoGrowWidth = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
2255 0 : if ( bIsAutoGrowWidth && !IsVerticalWriting() )
2256 0 : bIsAutoGrowWidth = !((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue();
2257 0 : return bIsAutoGrowWidth;
2258 : }
2259 :
2260 : /* The following method is identical to the SdrTextObj::SetVerticalWriting method, the only difference
2261 : is that the SdrAutoGrowWidthItem and SdrAutoGrowHeightItem are not exchanged if the vertical writing
2262 : mode has been changed */
2263 :
2264 0 : void SdrObjCustomShape::SetVerticalWriting( bool bVertical )
2265 : {
2266 0 : ForceOutlinerParaObject();
2267 :
2268 0 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2269 :
2270 : DBG_ASSERT( pOutlinerParaObject, "SdrTextObj::SetVerticalWriting() without OutlinerParaObject!" );
2271 :
2272 0 : if( pOutlinerParaObject )
2273 : {
2274 0 : if(pOutlinerParaObject->IsVertical() != (bool)bVertical)
2275 : {
2276 : // get item settings
2277 0 : const SfxItemSet& rSet = GetObjectItemSet();
2278 :
2279 : // Also exchange horizontal and vertical adjust items
2280 0 : SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
2281 0 : SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
2282 :
2283 : // rescue object size
2284 0 : Rectangle aObjectRect = GetSnapRect();
2285 :
2286 : // prepare ItemSet to set exchanged width and height items
2287 0 : SfxItemSet aNewSet(*rSet.GetPool(),
2288 : SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
2289 : // Expanded item ranges to also support horizontal and vertical adjust.
2290 : SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
2291 : SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
2292 0 : 0, 0);
2293 :
2294 0 : aNewSet.Put(rSet);
2295 :
2296 : // Exchange horizontal and vertical adjusts
2297 0 : switch(eVert)
2298 : {
2299 0 : case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
2300 0 : case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
2301 0 : case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
2302 0 : case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
2303 : }
2304 0 : switch(eHorz)
2305 : {
2306 0 : case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
2307 0 : case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
2308 0 : case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
2309 0 : case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
2310 : }
2311 :
2312 0 : pOutlinerParaObject = GetOutlinerParaObject();
2313 0 : if ( pOutlinerParaObject )
2314 0 : pOutlinerParaObject->SetVertical(bVertical);
2315 0 : SetObjectItemSet( aNewSet );
2316 :
2317 : // restore object size
2318 0 : SetSnapRect(aObjectRect);
2319 : }
2320 : }
2321 0 : }
2322 0 : bool SdrObjCustomShape::AdjustTextFrameWidthAndHeight(Rectangle& rR, bool bHgt, bool bWdt) const
2323 : {
2324 0 : if ( pModel && HasText() && !rR.IsEmpty() )
2325 : {
2326 0 : bool bWdtGrow=bWdt && IsAutoGrowWidth();
2327 0 : bool bHgtGrow=bHgt && IsAutoGrowHeight();
2328 0 : if ( bWdtGrow || bHgtGrow )
2329 : {
2330 0 : Rectangle aR0(rR);
2331 0 : long nHgt=0,nMinHgt=0,nMaxHgt=0;
2332 0 : long nWdt=0,nMinWdt=0,nMaxWdt=0;
2333 0 : Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--;
2334 0 : Size aMaxSiz(100000,100000);
2335 0 : Size aTmpSiz(pModel->GetMaxObjSize());
2336 0 : if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
2337 0 : if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
2338 0 : if (bWdtGrow)
2339 : {
2340 0 : nMinWdt=GetMinTextFrameWidth();
2341 0 : nMaxWdt=GetMaxTextFrameWidth();
2342 0 : if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
2343 0 : if (nMinWdt<=0) nMinWdt=1;
2344 0 : aSiz.Width()=nMaxWdt;
2345 : }
2346 0 : if (bHgtGrow)
2347 : {
2348 0 : nMinHgt=GetMinTextFrameHeight();
2349 0 : nMaxHgt=GetMaxTextFrameHeight();
2350 0 : if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
2351 0 : if (nMinHgt<=0) nMinHgt=1;
2352 0 : aSiz.Height()=nMaxHgt;
2353 : }
2354 0 : long nHDist=GetTextLeftDistance()+GetTextRightDistance();
2355 0 : long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
2356 0 : aSiz.Width()-=nHDist;
2357 0 : aSiz.Height()-=nVDist;
2358 0 : if ( aSiz.Width() < 2 )
2359 0 : aSiz.Width() = 2; // minimum size=2
2360 0 : if ( aSiz.Height() < 2 )
2361 0 : aSiz.Height() = 2; // minimum size=2
2362 :
2363 0 : if(pEdtOutl)
2364 : {
2365 0 : pEdtOutl->SetMaxAutoPaperSize( aSiz );
2366 0 : if (bWdtGrow)
2367 : {
2368 0 : Size aSiz2(pEdtOutl->CalcTextSize());
2369 0 : nWdt=aSiz2.Width()+1; // a little more tolerance
2370 0 : if (bHgtGrow) nHgt=aSiz2.Height()+1; // a little more tolerance
2371 : } else
2372 : {
2373 0 : nHgt=pEdtOutl->GetTextHeight()+1; // a little more tolerance
2374 : }
2375 : }
2376 : else
2377 : {
2378 0 : Outliner& rOutliner=ImpGetDrawOutliner();
2379 0 : rOutliner.SetPaperSize(aSiz);
2380 0 : rOutliner.SetUpdateMode(true);
2381 : // TODO: add the optimization with bPortionInfoChecked again.
2382 0 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2383 0 : if( pOutlinerParaObject != NULL )
2384 : {
2385 0 : rOutliner.SetText(*pOutlinerParaObject);
2386 0 : rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
2387 : }
2388 0 : if ( bWdtGrow )
2389 : {
2390 0 : Size aSiz2(rOutliner.CalcTextSize());
2391 0 : nWdt=aSiz2.Width()+1; // a little more tolerance
2392 0 : if ( bHgtGrow )
2393 0 : nHgt=aSiz2.Height()+1; // a little more tolerance
2394 : }
2395 : else
2396 0 : nHgt = rOutliner.GetTextHeight()+1; // a little more tolerance
2397 0 : rOutliner.Clear();
2398 : }
2399 0 : if ( nWdt < nMinWdt )
2400 0 : nWdt = nMinWdt;
2401 0 : if ( nWdt > nMaxWdt )
2402 0 : nWdt = nMaxWdt;
2403 0 : nWdt += nHDist;
2404 0 : if ( nWdt < 1 )
2405 0 : nWdt = 1; // nHDist may also be negative
2406 0 : if ( nHgt < nMinHgt )
2407 0 : nHgt = nMinHgt;
2408 0 : if ( nHgt > nMaxHgt )
2409 0 : nHgt = nMaxHgt;
2410 0 : nHgt+=nVDist;
2411 0 : if ( nHgt < 1 )
2412 0 : nHgt = 1; // nVDist may also be negative
2413 0 : long nWdtGrow = nWdt-(rR.Right()-rR.Left());
2414 0 : long nHgtGrow = nHgt-(rR.Bottom()-rR.Top());
2415 0 : if ( nWdtGrow == 0 )
2416 0 : bWdtGrow = false;
2417 0 : if ( nHgtGrow == 0 )
2418 0 : bHgtGrow=false;
2419 0 : if ( bWdtGrow || bHgtGrow )
2420 : {
2421 0 : if ( bWdtGrow )
2422 : {
2423 0 : SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
2424 0 : if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2425 0 : rR.Right()+=nWdtGrow;
2426 0 : else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2427 0 : rR.Left()-=nWdtGrow;
2428 : else
2429 : {
2430 0 : long nWdtGrow2=nWdtGrow/2;
2431 0 : rR.Left()-=nWdtGrow2;
2432 0 : rR.Right()=rR.Left()+nWdt;
2433 : }
2434 : }
2435 0 : if ( bHgtGrow )
2436 : {
2437 0 : SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
2438 0 : if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2439 0 : rR.Bottom()+=nHgtGrow;
2440 0 : else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2441 0 : rR.Top()-=nHgtGrow;
2442 : else
2443 : {
2444 0 : long nHgtGrow2=nHgtGrow/2;
2445 0 : rR.Top()-=nHgtGrow2;
2446 0 : rR.Bottom()=rR.Top()+nHgt;
2447 : }
2448 : }
2449 0 : if ( aGeo.nDrehWink )
2450 : {
2451 0 : Point aD1(rR.TopLeft());
2452 0 : aD1-=aR0.TopLeft();
2453 0 : Point aD2(aD1);
2454 0 : RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos);
2455 0 : aD2-=aD1;
2456 0 : rR.Move(aD2.X(),aD2.Y());
2457 : }
2458 0 : return true;
2459 : }
2460 : }
2461 : }
2462 0 : return false;
2463 : }
2464 :
2465 0 : Rectangle SdrObjCustomShape::ImpCalculateTextFrame( const bool bHgt, const bool bWdt )
2466 : {
2467 0 : Rectangle aReturnValue;
2468 :
2469 0 : Rectangle aOldTextRect( aRect ); // <- initial text rectangle
2470 :
2471 0 : Rectangle aNewTextRect( aRect ); // <- new text rectangle returned from the custom shape renderer,
2472 0 : GetTextBounds( aNewTextRect ); // it depends to the current logical shape size
2473 :
2474 0 : Rectangle aAdjustedTextRect( aNewTextRect ); // <- new text rectangle is being tested by AdjustTextFrameWidthAndHeight to ensure
2475 0 : if ( AdjustTextFrameWidthAndHeight( aAdjustedTextRect, bHgt, bWdt ) ) // that the new text rectangle is matching the current text size from the outliner
2476 : {
2477 0 : if ( ( aAdjustedTextRect != aNewTextRect ) && ( aOldTextRect != aAdjustedTextRect ) )
2478 : {
2479 0 : aReturnValue = aRect;
2480 0 : double fXScale = (double)aOldTextRect.GetWidth() / (double)aNewTextRect.GetWidth();
2481 0 : double fYScale = (double)aOldTextRect.GetHeight() / (double)aNewTextRect.GetHeight();
2482 0 : double fRightDiff = (double)( aAdjustedTextRect.Right() - aNewTextRect.Right() ) * fXScale;
2483 0 : double fLeftDiff = (double)( aAdjustedTextRect.Left() - aNewTextRect.Left() ) * fXScale;
2484 0 : double fTopDiff = (double)( aAdjustedTextRect.Top() - aNewTextRect.Top() ) * fYScale;
2485 0 : double fBottomDiff= (double)( aAdjustedTextRect.Bottom()- aNewTextRect.Bottom()) * fYScale;
2486 0 : aReturnValue.Left() += (sal_Int32)fLeftDiff;
2487 0 : aReturnValue.Right() += (sal_Int32)fRightDiff;
2488 0 : aReturnValue.Top() += (sal_Int32)fTopDiff;
2489 0 : aReturnValue.Bottom() += (sal_Int32)fBottomDiff;
2490 : }
2491 : }
2492 0 : return aReturnValue;
2493 : }
2494 :
2495 0 : bool SdrObjCustomShape::NbcAdjustTextFrameWidthAndHeight(bool bHgt, bool bWdt)
2496 : {
2497 0 : Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
2498 0 : bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
2499 0 : if ( bRet )
2500 : {
2501 : // taking care of handles that should not been changed
2502 0 : std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2503 :
2504 0 : aRect = aNewTextRect;
2505 0 : SetRectsDirty();
2506 0 : SetChanged();
2507 :
2508 0 : for (std::vector< SdrCustomShapeInteraction >::const_iterator aIter( aInteractionHandles.begin() ), aEnd ( aInteractionHandles.end() );
2509 : aIter != aEnd ; ++aIter)
2510 : {
2511 : try
2512 : {
2513 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2514 0 : aIter->xInteraction->setControllerPosition( aIter->aPosition );
2515 : }
2516 0 : catch ( const uno::RuntimeException& )
2517 : {
2518 : }
2519 : }
2520 0 : InvalidateRenderGeometry();
2521 : }
2522 0 : return bRet;
2523 : }
2524 0 : bool SdrObjCustomShape::AdjustTextFrameWidthAndHeight(bool bHgt, bool bWdt)
2525 : {
2526 0 : Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
2527 0 : bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
2528 0 : if ( bRet )
2529 : {
2530 0 : Rectangle aBoundRect0;
2531 0 : if ( pUserCall )
2532 0 : aBoundRect0 = GetCurrentBoundRect();
2533 :
2534 : // taking care of handles that should not been changed
2535 0 : std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
2536 :
2537 0 : aRect = aNewTextRect;
2538 0 : SetRectsDirty();
2539 :
2540 0 : for (std::vector< SdrCustomShapeInteraction >::const_iterator aIter( aInteractionHandles.begin() ), aEnd( aInteractionHandles.end() ) ;
2541 : aIter != aEnd ; ++aIter)
2542 : {
2543 : try
2544 : {
2545 0 : if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
2546 0 : aIter->xInteraction->setControllerPosition( aIter->aPosition );
2547 : }
2548 0 : catch ( const uno::RuntimeException& )
2549 : {
2550 : }
2551 : }
2552 :
2553 0 : InvalidateRenderGeometry();
2554 0 : SetChanged();
2555 0 : BroadcastObjectChange();
2556 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2557 : }
2558 0 : return bRet;
2559 : }
2560 0 : bool SdrObjCustomShape::BegTextEdit( SdrOutliner& rOutl )
2561 : {
2562 0 : return SdrTextObj::BegTextEdit( rOutl );
2563 : }
2564 0 : void SdrObjCustomShape::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
2565 : {
2566 0 : Size aPaperMin,aPaperMax;
2567 0 : Rectangle aViewInit;
2568 0 : TakeTextAnchorRect( aViewInit );
2569 0 : if ( aGeo.nDrehWink )
2570 : {
2571 0 : Point aCenter(aViewInit.Center());
2572 0 : aCenter-=aViewInit.TopLeft();
2573 0 : Point aCenter0(aCenter);
2574 0 : RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
2575 0 : aCenter-=aCenter0;
2576 0 : aViewInit.Move(aCenter.X(),aCenter.Y());
2577 : }
2578 0 : Size aAnkSiz(aViewInit.GetSize());
2579 0 : aAnkSiz.Width()--; aAnkSiz.Height()--; // because GetSize() adds 1
2580 0 : Size aMaxSiz(1000000,1000000);
2581 0 : if (pModel!=NULL) {
2582 0 : Size aTmpSiz(pModel->GetMaxObjSize());
2583 0 : if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
2584 0 : if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
2585 : }
2586 0 : SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
2587 0 : SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
2588 :
2589 0 : long nMinWdt = GetMinTextFrameWidth();
2590 0 : long nMinHgt = GetMinTextFrameHeight();
2591 0 : long nMaxWdt = GetMaxTextFrameWidth();
2592 0 : long nMaxHgt = GetMaxTextFrameHeight();
2593 0 : if (nMinWdt<1) nMinWdt=1;
2594 0 : if (nMinHgt<1) nMinHgt=1;
2595 0 : if ( nMaxWdt == 0 || nMaxWdt > aMaxSiz.Width() )
2596 0 : nMaxWdt = aMaxSiz.Width();
2597 0 : if ( nMaxHgt == 0 || nMaxHgt > aMaxSiz.Height() )
2598 0 : nMaxHgt=aMaxSiz.Height();
2599 :
2600 0 : if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
2601 : {
2602 0 : if ( IsVerticalWriting() )
2603 : {
2604 0 : nMaxHgt = aAnkSiz.Height();
2605 0 : nMinHgt = nMaxHgt;
2606 : }
2607 : else
2608 : {
2609 0 : nMaxWdt = aAnkSiz.Width();
2610 0 : nMinWdt = nMaxWdt;
2611 : }
2612 : }
2613 0 : aPaperMax.Width()=nMaxWdt;
2614 0 : aPaperMax.Height()=nMaxHgt;
2615 :
2616 0 : aPaperMin.Width()=nMinWdt;
2617 0 : aPaperMin.Height()=nMinHgt;
2618 :
2619 0 : if ( pViewMin )
2620 : {
2621 0 : *pViewMin = aViewInit;
2622 :
2623 0 : long nXFree = aAnkSiz.Width() - aPaperMin.Width();
2624 0 : if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2625 0 : pViewMin->Right() -= nXFree;
2626 0 : else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2627 0 : pViewMin->Left() += nXFree;
2628 0 : else { pViewMin->Left() += nXFree / 2; pViewMin->Right() = pViewMin->Left() + aPaperMin.Width(); }
2629 :
2630 0 : long nYFree = aAnkSiz.Height() - aPaperMin.Height();
2631 0 : if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2632 0 : pViewMin->Bottom() -= nYFree;
2633 0 : else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2634 0 : pViewMin->Top() += nYFree;
2635 0 : else { pViewMin->Top() += nYFree / 2; pViewMin->Bottom() = pViewMin->Top() + aPaperMin.Height(); }
2636 : }
2637 :
2638 0 : if( IsVerticalWriting() )
2639 0 : aPaperMin.Width() = 0;
2640 : else
2641 0 : aPaperMin.Height() = 0;
2642 :
2643 0 : if( eHAdj != SDRTEXTHORZADJUST_BLOCK )
2644 0 : aPaperMin.Width()=0;
2645 :
2646 : // For complete vertical adjust support, set paper min height to 0, here.
2647 0 : if(SDRTEXTVERTADJUST_BLOCK != eVAdj )
2648 0 : aPaperMin.Height() = 0;
2649 :
2650 0 : if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
2651 0 : if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
2652 0 : if (pViewInit!=NULL) *pViewInit=aViewInit;
2653 0 : }
2654 0 : void SdrObjCustomShape::EndTextEdit( SdrOutliner& rOutl )
2655 : {
2656 0 : SdrTextObj::EndTextEdit( rOutl );
2657 0 : InvalidateRenderGeometry();
2658 0 : }
2659 0 : void SdrObjCustomShape::TakeTextAnchorRect( Rectangle& rAnchorRect ) const
2660 : {
2661 0 : if ( GetTextBounds( rAnchorRect ) )
2662 : {
2663 0 : Point aRotateRef( maSnapRect.Center() );
2664 0 : rAnchorRect.Left() += GetTextLeftDistance();
2665 0 : rAnchorRect.Top() += GetTextUpperDistance();
2666 0 : rAnchorRect.Right() -= GetTextRightDistance();
2667 0 : rAnchorRect.Bottom() -= GetTextLowerDistance();
2668 0 : ImpJustifyRect( rAnchorRect );
2669 :
2670 0 : if ( rAnchorRect.GetWidth() < 2 )
2671 0 : rAnchorRect.Right() = rAnchorRect.Left() + 1; // minimal width is 2
2672 0 : if ( rAnchorRect.GetHeight() < 2 )
2673 0 : rAnchorRect.Bottom() = rAnchorRect.Top() + 1; // minimal height is 2
2674 0 : if ( aGeo.nDrehWink )
2675 : {
2676 0 : Point aP( rAnchorRect.TopLeft() );
2677 0 : RotatePoint( aP, aRotateRef, aGeo.nSin, aGeo. nCos );
2678 0 : rAnchorRect.SetPos( aP );
2679 : }
2680 : }
2681 : else
2682 0 : SdrTextObj::TakeTextAnchorRect( rAnchorRect );
2683 0 : }
2684 0 : void SdrObjCustomShape::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, bool bNoEditText,
2685 : Rectangle* pAnchorRect, bool /*bLineWidth*/) const
2686 : {
2687 0 : Rectangle aAnkRect; // Rect in which we anchor
2688 0 : TakeTextAnchorRect(aAnkRect);
2689 0 : SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
2690 0 : SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
2691 0 : sal_uIntPtr nStat0=rOutliner.GetControlWord();
2692 0 : Size aNullSize;
2693 :
2694 0 : rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
2695 0 : rOutliner.SetMinAutoPaperSize(aNullSize);
2696 0 : sal_Int32 nMaxAutoPaperWidth = 1000000;
2697 0 : sal_Int32 nMaxAutoPaperHeight= 1000000;
2698 :
2699 0 : long nAnkWdt=aAnkRect.GetWidth();
2700 0 : long nAnkHgt=aAnkRect.GetHeight();
2701 :
2702 0 : if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
2703 : {
2704 0 : if ( IsVerticalWriting() )
2705 0 : nMaxAutoPaperHeight = nAnkHgt;
2706 : else
2707 0 : nMaxAutoPaperWidth = nAnkWdt;
2708 : }
2709 0 : if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
2710 : {
2711 0 : rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
2712 : }
2713 :
2714 0 : if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
2715 : {
2716 0 : rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
2717 : }
2718 0 : rOutliner.SetMaxAutoPaperSize( Size( nMaxAutoPaperWidth, nMaxAutoPaperHeight ) );
2719 0 : rOutliner.SetPaperSize( aNullSize );
2720 :
2721 : // put text into the Outliner - if necessary the use the text from the EditOutliner
2722 0 : OutlinerParaObject* pPara= GetOutlinerParaObject();
2723 0 : if (pEdtOutl && !bNoEditText)
2724 0 : pPara=pEdtOutl->CreateParaObject();
2725 :
2726 0 : if (pPara)
2727 : {
2728 0 : bool bHitTest = false;
2729 0 : if( pModel )
2730 0 : bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
2731 :
2732 0 : const SdrTextObj* pTestObj = rOutliner.GetTextObj();
2733 0 : if( !pTestObj || !bHitTest || pTestObj != this ||
2734 0 : pTestObj->GetOutlinerParaObject() != GetOutlinerParaObject() )
2735 : {
2736 0 : if( bHitTest )
2737 0 : rOutliner.SetTextObj( this );
2738 :
2739 0 : rOutliner.SetUpdateMode(true);
2740 0 : rOutliner.SetText(*pPara);
2741 : }
2742 : }
2743 : else
2744 : {
2745 0 : rOutliner.SetTextObj( NULL );
2746 : }
2747 0 : if (pEdtOutl && !bNoEditText && pPara)
2748 0 : delete pPara;
2749 :
2750 0 : rOutliner.SetUpdateMode(true);
2751 0 : rOutliner.SetControlWord(nStat0);
2752 :
2753 0 : SdrText* pText = getActiveText();
2754 0 : if( pText )
2755 0 : pText->CheckPortionInfo( rOutliner );
2756 :
2757 0 : Point aTextPos(aAnkRect.TopLeft());
2758 0 : Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() has a little added tolerance, no?
2759 :
2760 : // For draw objects containing text correct horizontal/vertical alignment if text is bigger
2761 : // than the object itself. Without that correction, the text would always be
2762 : // formatted to the left edge (or top edge when vertical) of the draw object.
2763 :
2764 0 : if( !IsTextFrame() )
2765 : {
2766 0 : if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
2767 : {
2768 : // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
2769 : // else the alignment is wanted.
2770 0 : if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
2771 : {
2772 0 : eHAdj = SDRTEXTHORZADJUST_CENTER;
2773 : }
2774 : }
2775 :
2776 0 : if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
2777 : {
2778 : // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
2779 : // else the alignment is wanted.
2780 0 : if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
2781 : {
2782 0 : eVAdj = SDRTEXTVERTADJUST_CENTER;
2783 : }
2784 : }
2785 : }
2786 :
2787 0 : if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
2788 : {
2789 0 : long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
2790 0 : if (eHAdj==SDRTEXTHORZADJUST_CENTER)
2791 0 : aTextPos.X()+=nFreeWdt/2;
2792 0 : if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
2793 0 : aTextPos.X()+=nFreeWdt;
2794 : }
2795 0 : if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
2796 : {
2797 0 : long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
2798 0 : if (eVAdj==SDRTEXTVERTADJUST_CENTER)
2799 0 : aTextPos.Y()+=nFreeHgt/2;
2800 0 : if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
2801 0 : aTextPos.Y()+=nFreeHgt;
2802 : }
2803 0 : if (aGeo.nDrehWink!=0)
2804 0 : RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
2805 :
2806 0 : if (pAnchorRect)
2807 0 : *pAnchorRect=aAnkRect;
2808 :
2809 : // using rTextRect together with ContourFrame doesn't always work correctly
2810 0 : rTextRect=Rectangle(aTextPos,aTextSiz);
2811 0 : }
2812 :
2813 0 : void SdrObjCustomShape::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
2814 : {
2815 0 : SdrTextObj::NbcSetOutlinerParaObject( pTextObject );
2816 0 : SetBoundRectDirty();
2817 0 : SetRectsDirty(true);
2818 0 : InvalidateRenderGeometry();
2819 0 : }
2820 :
2821 0 : SdrObjCustomShape* SdrObjCustomShape::Clone() const
2822 : {
2823 0 : return CloneHelper< SdrObjCustomShape >();
2824 : }
2825 :
2826 0 : SdrObjCustomShape& SdrObjCustomShape::operator=(const SdrObjCustomShape& rObj)
2827 : {
2828 0 : if( this == &rObj )
2829 0 : return *this;
2830 0 : SdrTextObj::operator=( rObj );
2831 0 : aName = rObj.aName;
2832 0 : fObjectRotation = rObj.fObjectRotation;
2833 0 : InvalidateRenderGeometry();
2834 0 : return *this;
2835 : }
2836 :
2837 :
2838 0 : OUString SdrObjCustomShape::TakeObjNameSingul() const
2839 : {
2840 0 : OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulCUSTOMSHAPE));
2841 0 : OUString aNm(GetName());
2842 0 : if (!aNm.isEmpty())
2843 : {
2844 0 : sName.append(' ');
2845 0 : sName.append('\'');
2846 0 : sName.append(aNm);
2847 0 : sName.append('\'');
2848 : }
2849 0 : return sName.makeStringAndClear();
2850 : }
2851 :
2852 0 : OUString SdrObjCustomShape::TakeObjNamePlural() const
2853 : {
2854 0 : return ImpGetResStr(STR_ObjNamePluralCUSTOMSHAPE);
2855 : }
2856 :
2857 0 : basegfx::B2DPolyPolygon SdrObjCustomShape::TakeXorPoly() const
2858 : {
2859 0 : return GetLineGeometry( (SdrObjCustomShape*)this, false );
2860 : }
2861 :
2862 0 : basegfx::B2DPolyPolygon SdrObjCustomShape::TakeContour() const
2863 : {
2864 0 : const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
2865 0 : if ( pSdrObject )
2866 0 : return pSdrObject->TakeContour();
2867 0 : return basegfx::B2DPolyPolygon();
2868 : }
2869 :
2870 0 : SdrObject* SdrObjCustomShape::DoConvertToPolyObj(bool bBezier, bool bAddText) const
2871 : {
2872 : // #i37011#
2873 0 : SdrObject* pRetval = 0L;
2874 0 : SdrObject* pRenderedCustomShape = 0L;
2875 :
2876 0 : if ( !mXRenderedCustomShape.is() )
2877 : {
2878 : // force CustomShape
2879 0 : ((SdrObjCustomShape*)this)->GetSdrObjectFromCustomShape();
2880 : }
2881 :
2882 0 : if ( mXRenderedCustomShape.is() )
2883 : {
2884 0 : pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
2885 : }
2886 :
2887 0 : if ( pRenderedCustomShape )
2888 : {
2889 0 : SdrObject* pCandidate = pRenderedCustomShape->Clone();
2890 : DBG_ASSERT(pCandidate, "SdrObjCustomShape::DoConvertToPolyObj: Could not clone SdrObject (!)");
2891 0 : pCandidate->SetModel(GetModel());
2892 0 : pRetval = pCandidate->DoConvertToPolyObj(bBezier, bAddText);
2893 0 : SdrObject::Free( pCandidate );
2894 :
2895 0 : if(pRetval)
2896 : {
2897 0 : const bool bShadow(((SdrShadowItem&)GetMergedItem(SDRATTR_SHADOW)).GetValue());
2898 0 : if(bShadow)
2899 : {
2900 0 : pRetval->SetMergedItem(SdrShadowItem(true));
2901 : }
2902 : }
2903 :
2904 0 : if(bAddText && HasText() && !IsTextPath())
2905 : {
2906 0 : pRetval = ImpConvertAddText(pRetval, bBezier);
2907 : }
2908 : }
2909 :
2910 0 : return pRetval;
2911 : }
2912 :
2913 0 : void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr )
2914 : {
2915 : // #i40944#
2916 0 : InvalidateRenderGeometry();
2917 0 : SdrObject::NbcSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr );
2918 0 : }
2919 :
2920 0 : void SdrObjCustomShape::SetPage( SdrPage* pNewPage )
2921 : {
2922 0 : SdrTextObj::SetPage( pNewPage );
2923 :
2924 0 : if( pNewPage )
2925 : {
2926 : // invalidating rectangles by SetRectsDirty is not sufficient,
2927 : // AdjustTextFrameWidthAndHeight() also has to be made, both
2928 : // actions are done by NbcSetSnapRect
2929 0 : Rectangle aTmp( aRect ); //creating temporary rectangle #i61108#
2930 0 : NbcSetSnapRect( aTmp );
2931 : }
2932 0 : }
2933 :
2934 0 : SdrObjGeoData* SdrObjCustomShape::NewGeoData() const
2935 : {
2936 0 : return new SdrAShapeObjGeoData;
2937 : }
2938 :
2939 0 : void SdrObjCustomShape::SaveGeoData(SdrObjGeoData& rGeo) const
2940 : {
2941 0 : SdrTextObj::SaveGeoData( rGeo );
2942 0 : SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
2943 0 : rAGeo.fObjectRotation = fObjectRotation;
2944 0 : rAGeo.bMirroredX = IsMirroredX();
2945 0 : rAGeo.bMirroredY = IsMirroredY();
2946 :
2947 0 : const OUString sAdjustmentValues( "AdjustmentValues" );
2948 0 : Any* pAny( ( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ).GetPropertyValueByName( sAdjustmentValues ) );
2949 0 : if ( pAny )
2950 0 : *pAny >>= rAGeo.aAdjustmentSeq;
2951 0 : }
2952 :
2953 0 : void SdrObjCustomShape::RestGeoData(const SdrObjGeoData& rGeo)
2954 : {
2955 0 : SdrTextObj::RestGeoData( rGeo );
2956 0 : SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
2957 0 : fObjectRotation = rAGeo.fObjectRotation;
2958 0 : SetMirroredX( rAGeo.bMirroredX );
2959 0 : SetMirroredY( rAGeo.bMirroredY );
2960 :
2961 0 : SdrCustomShapeGeometryItem rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
2962 0 : const OUString sAdjustmentValues( "AdjustmentValues" );
2963 0 : PropertyValue aPropVal;
2964 0 : aPropVal.Name = sAdjustmentValues;
2965 0 : aPropVal.Value <<= rAGeo.aAdjustmentSeq;
2966 0 : rGeometryItem.SetPropertyValue( aPropVal );
2967 0 : SetMergedItem( rGeometryItem );
2968 :
2969 0 : InvalidateRenderGeometry();
2970 0 : }
2971 :
2972 0 : void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
2973 : {
2974 : // break up matrix
2975 0 : basegfx::B2DTuple aScale;
2976 0 : basegfx::B2DTuple aTranslate;
2977 : double fRotate, fShearX;
2978 0 : rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
2979 :
2980 : // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
2981 : // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
2982 0 : if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
2983 : {
2984 0 : aScale.setX(fabs(aScale.getX()));
2985 0 : aScale.setY(fabs(aScale.getY()));
2986 0 : fRotate = fmod(fRotate + F_PI, F_2PI);
2987 : }
2988 :
2989 : // reset object shear and rotations
2990 0 : aGeo.nDrehWink = 0;
2991 0 : aGeo.RecalcSinCos();
2992 0 : aGeo.nShearWink = 0;
2993 0 : aGeo.RecalcTan();
2994 :
2995 : // force metric to pool metric
2996 0 : const SfxMapUnit eMapUnit(GetObjectMapUnit());
2997 0 : if(eMapUnit != SFX_MAPUNIT_100TH_MM)
2998 : {
2999 0 : switch(eMapUnit)
3000 : {
3001 : case SFX_MAPUNIT_TWIP :
3002 : {
3003 : // position
3004 0 : aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
3005 0 : aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
3006 :
3007 : // size
3008 0 : aScale.setX(ImplMMToTwips(aScale.getX()));
3009 0 : aScale.setY(ImplMMToTwips(aScale.getY()));
3010 :
3011 0 : break;
3012 : }
3013 : default:
3014 : {
3015 : OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
3016 : }
3017 : }
3018 : }
3019 :
3020 : // if anchor is used, make position relative to it
3021 0 : if( pModel && pModel->IsWriter() )
3022 : {
3023 0 : if(GetAnchorPos().X() || GetAnchorPos().Y())
3024 : {
3025 0 : aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3026 : }
3027 : }
3028 :
3029 : // build and set BaseRect (use scale)
3030 0 : Point aPoint = Point();
3031 0 : Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
3032 : // fdo#47434 We need a valid rectangle here
3033 0 : if( !aSize.Height() ) aSize.setHeight( 1 );
3034 0 : if( !aSize.Width() ) aSize.setWidth( 1 );
3035 :
3036 0 : Rectangle aBaseRect(aPoint, aSize);
3037 0 : SetSnapRect(aBaseRect);
3038 :
3039 : // shear?
3040 0 : if(!basegfx::fTools::equalZero(fShearX))
3041 : {
3042 0 : GeoStat aGeoStat;
3043 : // #i123181# The fix for #121932# here was wrong, the trunk version does not correct the
3044 : // mirrored shear values, neither at the object level, nor on the API or XML level. Taking
3045 : // back the mirroring of the shear angle
3046 0 : aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
3047 0 : aGeoStat.RecalcTan();
3048 0 : Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, false);
3049 : }
3050 :
3051 : // rotation?
3052 0 : if(!basegfx::fTools::equalZero(fRotate))
3053 : {
3054 0 : GeoStat aGeoStat;
3055 :
3056 : // #i78696#
3057 : // fRotate is mathematically correct, but aGeoStat.nDrehWink is
3058 : // mirrored -> mirror value here
3059 0 : aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
3060 0 : aGeoStat.RecalcSinCos();
3061 0 : Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
3062 : }
3063 :
3064 : // translate?
3065 0 : if(!aTranslate.equalZero())
3066 : {
3067 0 : Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
3068 0 : }
3069 0 : }
3070 :
3071 : // taking fObjectRotation instead of aGeo.nWink
3072 0 : bool SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
3073 : {
3074 : // get turn and shear
3075 0 : double fRotate = fObjectRotation * F_PI180;
3076 0 : double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
3077 :
3078 : // get aRect, this is the unrotated snaprect
3079 0 : Rectangle aRectangle(aRect);
3080 :
3081 0 : bool bMirroredX = IsMirroredX();
3082 0 : bool bMirroredY = IsMirroredY();
3083 0 : if ( bMirroredX || bMirroredY )
3084 : { // we have to retrieve the unmirrored rect
3085 :
3086 0 : GeoStat aNewGeo( aGeo );
3087 :
3088 0 : if ( bMirroredX )
3089 : {
3090 0 : Polygon aPol( Rect2Poly( aRect, aNewGeo ) );
3091 0 : Rectangle aBoundRect( aPol.GetBoundRect() );
3092 :
3093 0 : Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
3094 0 : Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
3095 : sal_uInt16 i;
3096 0 : sal_uInt16 nPntAnz=aPol.GetSize();
3097 0 : for (i=0; i<nPntAnz; i++)
3098 : {
3099 0 : MirrorPoint(aPol[i],aRef1,aRef2);
3100 : }
3101 : // mirror polygon and move it a bit
3102 0 : Polygon aPol0(aPol);
3103 0 : aPol[0]=aPol0[1];
3104 0 : aPol[1]=aPol0[0];
3105 0 : aPol[2]=aPol0[3];
3106 0 : aPol[3]=aPol0[2];
3107 0 : aPol[4]=aPol0[1];
3108 0 : Poly2Rect(aPol,aRectangle,aNewGeo);
3109 : }
3110 0 : if ( bMirroredY )
3111 : {
3112 0 : Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
3113 0 : Rectangle aBoundRect( aPol.GetBoundRect() );
3114 :
3115 0 : Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
3116 0 : Point aRef2( aRef1.X() + 1000, aRef1.Y() );
3117 : sal_uInt16 i;
3118 0 : sal_uInt16 nPntAnz=aPol.GetSize();
3119 0 : for (i=0; i<nPntAnz; i++)
3120 : {
3121 0 : MirrorPoint(aPol[i],aRef1,aRef2);
3122 : }
3123 : // mirror polygon and move it a bit
3124 0 : Polygon aPol0(aPol);
3125 0 : aPol[0]=aPol0[1]; // This was WRONG for vertical (!)
3126 0 : aPol[1]=aPol0[0]; // #i121932# Despite my own coment above
3127 0 : aPol[2]=aPol0[3]; // it was *not* wrong even when the reordering
3128 0 : aPol[3]=aPol0[2]; // *seems* to be specific for X-Mirrorings. Oh
3129 0 : aPol[4]=aPol0[1]; // will I be happy when this old stuff is |gone| with aw080 (!)
3130 0 : Poly2Rect(aPol,aRectangle,aNewGeo);
3131 : }
3132 : }
3133 :
3134 : // fill other values
3135 0 : basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
3136 0 : basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
3137 :
3138 : // position may be relative to anchorpos, convert
3139 0 : if( pModel && pModel->IsWriter() )
3140 : {
3141 0 : if(GetAnchorPos().X() || GetAnchorPos().Y())
3142 : {
3143 0 : aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3144 : }
3145 : }
3146 :
3147 : // force MapUnit to 100th mm
3148 0 : const SfxMapUnit eMapUnit(GetObjectMapUnit());
3149 0 : if(eMapUnit != SFX_MAPUNIT_100TH_MM)
3150 : {
3151 0 : switch(eMapUnit)
3152 : {
3153 : case SFX_MAPUNIT_TWIP :
3154 : {
3155 : // position
3156 0 : aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
3157 0 : aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
3158 :
3159 : // size
3160 0 : aScale.setX(ImplTwipsToMM(aScale.getX()));
3161 0 : aScale.setY(ImplTwipsToMM(aScale.getY()));
3162 :
3163 0 : break;
3164 : }
3165 : default:
3166 : {
3167 : OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
3168 : }
3169 : }
3170 : }
3171 :
3172 : // build matrix
3173 0 : rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
3174 : aScale,
3175 0 : basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
3176 0 : basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
3177 0 : aTranslate);
3178 :
3179 0 : return false;
3180 : }
3181 :
3182 0 : sdr::contact::ViewContact* SdrObjCustomShape::CreateObjectSpecificViewContact()
3183 : {
3184 0 : return new sdr::contact::ViewContactOfSdrObjCustomShape(*this);
3185 : }
3186 :
3187 : // #i33136#
3188 0 : bool SdrObjCustomShape::doConstructOrthogonal(const OUString& rName)
3189 : {
3190 0 : bool bRetval(false);
3191 0 : static OUString Imps_sNameASOrtho_quadrat( "quadrat" );
3192 0 : static OUString Imps_sNameASOrtho_round_quadrat( "round-quadrat" );
3193 0 : static OUString Imps_sNameASOrtho_circle( "circle" );
3194 0 : static OUString Imps_sNameASOrtho_circle_pie( "circle-pie" );
3195 0 : static OUString Imps_sNameASOrtho_ring( "ring" );
3196 :
3197 0 : if(Imps_sNameASOrtho_quadrat.equalsIgnoreAsciiCase(rName))
3198 : {
3199 0 : bRetval = true;
3200 : }
3201 0 : else if(Imps_sNameASOrtho_round_quadrat.equalsIgnoreAsciiCase(rName))
3202 : {
3203 0 : bRetval = true;
3204 : }
3205 0 : else if(Imps_sNameASOrtho_circle.equalsIgnoreAsciiCase(rName))
3206 : {
3207 0 : bRetval = true;
3208 : }
3209 0 : else if(Imps_sNameASOrtho_circle_pie.equalsIgnoreAsciiCase(rName))
3210 : {
3211 0 : bRetval = true;
3212 : }
3213 0 : else if(Imps_sNameASOrtho_ring.equalsIgnoreAsciiCase(rName))
3214 : {
3215 0 : bRetval = true;
3216 : }
3217 :
3218 0 : return bRetval;
3219 : }
3220 :
3221 : // #i37011# centralize throw-away of render geometry
3222 0 : void SdrObjCustomShape::InvalidateRenderGeometry()
3223 : {
3224 0 : mXRenderedCustomShape = 0L;
3225 0 : SdrObject::Free( mpLastShadowGeometry );
3226 0 : mpLastShadowGeometry = 0L;
3227 0 : }
3228 :
3229 0 : void SdrObjCustomShape::impl_setUnoShape(const uno::Reference<uno::XInterface>& rxUnoShape)
3230 : {
3231 0 : SdrTextObj::impl_setUnoShape(rxUnoShape);
3232 :
3233 : // The shape engine is created with _current_ shape. This means we
3234 : // _must_ reset it when the shape changes.
3235 0 : mxCustomShapeEngine.set(0);
3236 0 : }
3237 :
3238 0 : OUString SdrObjCustomShape::GetCustomShapeName()
3239 : {
3240 0 : OUString sShapeName;
3241 0 : OUString aEngine( ( (SdrCustomShapeEngineItem&)( *this ).GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ) ).GetValue() );
3242 0 : if ( aEngine.isEmpty() || aEngine.equalsAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) )
3243 : {
3244 0 : OUString sShapeType;
3245 0 : const OUString sType("Type");
3246 0 : SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)( *this ).GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
3247 0 : Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
3248 0 : if ( pAny && ( *pAny >>= sShapeType ) )
3249 0 : sShapeName = EnhancedCustomShapeTypeNames::GetAccName( sShapeType );
3250 : }
3251 0 : return sShapeName;
3252 : }
3253 :
3254 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|