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