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