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