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