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