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