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