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 basegfx::BGradient aGradient(rOriginalSet.Get(XATTR_FILLGRADIENT).GetGradientValue());
306 sal_uInt8 nStartLuminance(Color(aGradient.GetColorStops().front().getStopColor()).GetLuminance());
307 sal_uInt8 nEndLuminance(Color(aGradient.GetColorStops().back().getStopColor()).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.SetColorStops(
331 aStartColor.getBColor(),
332 aEndColor.getBColor()));
333 aTempSet.Put(XFillGradientItem(aGradient));
334 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
335 }
336
337 // hatch and transparency like shadow
338 if(bHatchFillUsed)
339 {
340 XHatch aHatch(rOriginalSet.Get(XATTR_FILLHATCH).GetHatchValue());
341 aHatch.SetColor(aShadowColor);
342 aTempSet.Put(XFillHatchItem(aHatch));
343 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
344 }
345
346 // bitmap and transparency like shadow
347 if(bBitmapFillUsed)
348 {
349 GraphicObject aGraphicObject(rOriginalSet.Get(XATTR_FILLBITMAP).GetGraphicObject());
350 BitmapEx aBitmapEx(aGraphicObject.GetGraphic().GetBitmapEx());
351
352 if(!aBitmapEx.IsEmpty())
353 {
355 pVirDev->SetOutputSizePixel(aBitmapEx.GetSizePixel());
356 BitmapFilter::Filter(aBitmapEx, BitmapShadowFilter(aShadowColor));
357 pVirDev->DrawBitmapEx(Point(), aBitmapEx);
358 aGraphicObject.SetGraphic(Graphic(pVirDev->GetBitmapEx(Point(0,0), aBitmapEx.GetSizePixel())));
359 }
360
361 aTempSet.Put(XFillBitmapItem(aGraphicObject));
362 aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
363 }
364
365 // set attributes and paint shadow object
366 pRetval->SetMergedItemSet( aTempSet );
367 }
368 return pRetval;
369}
370
371
372uno::Reference<drawing::XCustomShapeEngine> const & SdrObjCustomShape::GetCustomShapeEngine() const
373{
374 if (mxCustomShapeEngine.is())
375 return mxCustomShapeEngine;
376
377 uno::Reference<drawing::XShape> aXShape = GetXShapeForSdrObject(const_cast<SdrObjCustomShape*>(this));
378 if ( !aXShape )
379 return mxCustomShapeEngine;
380
381 uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
382
384 static constexpr OUStringLiteral sEnhancedCustomShapeEngine = u"com.sun.star.drawing.EnhancedCustomShapeEngine";
385 if ( aEngine.isEmpty() )
386 aEngine = sEnhancedCustomShapeEngine;
387
388 {
389 static constexpr OUStringLiteral sCustomShape = u"CustomShape";
390 uno::Sequence<beans::PropertyValue> aPropValues{ comphelper::makePropertyValue(sCustomShape,
391 aXShape) };
392 uno::Sequence<uno::Any> aArgument{ uno::Any(aPropValues) };
393 try
394 {
395 uno::Reference<uno::XInterface> xInterface(xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aEngine, aArgument, xContext));
396 if (xInterface.is())
397 mxCustomShapeEngine.set(xInterface, uno::UNO_QUERY);
398 }
399 catch (const loader::CannotActivateFactoryException&)
400 {
401 }
402 }
403
404 return mxCustomShapeEngine;
405}
406
408{
409 if ( !mXRenderedCustomShape.is() )
410 {
411 uno::Reference<drawing::XCustomShapeEngine> xCustomShapeEngine( GetCustomShapeEngine() );
412 if ( xCustomShapeEngine.is() )
413 const_cast<SdrObjCustomShape*>(this)->mXRenderedCustomShape = xCustomShapeEngine->render();
414 }
415 SdrObject* pRenderedCustomShape = mXRenderedCustomShape.is()
417 : nullptr;
418 return pRenderedCustomShape;
419}
420
421// #i37011# Shadow geometry creation
423{
425 {
426 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
427 if(pSdrObject)
428 {
429 const SfxItemSet& rOriginalSet = GetObjectItemSet();
430 const bool bShadow(rOriginalSet.Get( SDRATTR_SHADOW ).GetValue());
431
432 if(bShadow)
433 {
434 // create a clone with all attributes changed to shadow attributes
435 // and translation executed, too.
436 const_cast<SdrObjCustomShape*>(this)->mpLastShadowGeometry =
437 ImpCreateShadowObjectClone(*pSdrObject, rOriginalSet);
438 }
439 }
440 }
441
442 return mpLastShadowGeometry.get();
443}
444
446{
447 static constexpr OUStringLiteral sTextPath( u"TextPath" );
448 bool bTextPathOn = false;
450 const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
451 if ( pAny )
452 *pAny >>= bTextPathOn;
453 return bTextPathOn;
454}
455
457{
458 bool bRet = false;
459 OUString sShapeType;
460 static constexpr OUStringLiteral sType( u"Type" );
462 const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
463 if ( pAny )
464 *pAny >>= sShapeType;
466
467 return bRet;
468}
469
471{
472 bool bMirroredX = false;
474 const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "MirroredX" );
475 if ( pAny )
476 *pAny >>= bMirroredX;
477 return bMirroredX;
478}
480{
481 bool bMirroredY = false;
483 const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "MirroredY" );
484 if ( pAny )
485 *pAny >>= bMirroredY;
486 return bMirroredY;
487}
488void SdrObjCustomShape::SetMirroredX( const bool bMirrorX )
489{
491 beans::PropertyValue aPropVal;
492 aPropVal.Name = "MirroredX";
493 aPropVal.Value <<= bMirrorX;
494 aGeometryItem.SetPropertyValue( aPropVal );
495 SetMergedItem( aGeometryItem );
496}
497void SdrObjCustomShape::SetMirroredY( const bool bMirrorY )
498{
500 beans::PropertyValue aPropVal;
501 aPropVal.Name = "MirroredY";
502 aPropVal.Value <<= bMirrorY;
503 aGeometryItem.SetPropertyValue( aPropVal );
504 SetMergedItem( aGeometryItem );
505}
506
507double SdrObjCustomShape::GetExtraTextRotation( const bool bPreRotation ) const
508{
509 double fExtraTextRotateAngle = 0.0;
510 if (bPreRotation)
511 {
512 // textPreRotateAngle might be set by macro or diagram (SmartArt) import
513 const uno::Any* pAny;
515 pAny = rGeometryItem.GetPropertyValueByName(u"TextPreRotateAngle");
516 if ( pAny )
517 *pAny >>= fExtraTextRotateAngle;
518
519 // As long as the edit engine is not able to render these text directions we
520 // emulate them by setting a suitable text pre-rotation.
522 if (rDirectionItem.GetValue() == SvxFrameDirection::Vertical_RL_TB90)
523 fExtraTextRotateAngle -= 90;
524 else if (rDirectionItem.GetValue() == SvxFrameDirection::Vertical_LR_BT)
525 fExtraTextRotateAngle -=270;
526 }
527 else
528 {
529 const uno::Any* pAny;
531 pAny = rGeometryItem.GetPropertyValueByName(u"TextRotateAngle");
532 if ( pAny )
533 *pAny >>= fExtraTextRotateAngle;
534 }
535 return fExtraTextRotateAngle;
536}
537
539{
540 bool bRet = false;
541
542 uno::Reference<drawing::XCustomShapeEngine> xCustomShapeEngine( GetCustomShapeEngine() );
543 if ( xCustomShapeEngine.is() )
544 {
545 awt::Rectangle aR( xCustomShapeEngine->getTextBounds() );
546 if ( aR.Width > 1 && aR.Height > 1 )
547 {
548 rTextBound = tools::Rectangle( Point( aR.X, aR.Y ), Size( aR.Width, aR.Height ) );
549 bRet = true;
550 }
551 }
552 return bRet;
553}
555{
557 uno::Reference<drawing::XCustomShapeEngine> xCustomShapeEngine( GetCustomShapeEngine() );
558 if ( xCustomShapeEngine.is() )
559 {
560 drawing::PolyPolygonBezierCoords aBezierCoords = xCustomShapeEngine->getLineGeometry();
561 try
562 {
564 if ( !bBezierAllowed && aRetval.areControlPointsUsed())
565 {
567 }
568 }
569 catch ( const lang::IllegalArgumentException & )
570 {
571 }
572 }
573 return aRetval;
574}
575
576std::vector< SdrCustomShapeInteraction > SdrObjCustomShape::GetInteractionHandles() const
577{
578 std::vector< SdrCustomShapeInteraction > aRet;
579 try
580 {
581 uno::Reference<drawing::XCustomShapeEngine> xCustomShapeEngine( GetCustomShapeEngine() );
582 if ( xCustomShapeEngine.is() )
583 {
584 int i;
585 uno::Sequence<uno::Reference<drawing::XCustomShapeHandle>> xInteractionHandles( xCustomShapeEngine->getInteraction() );
586 for ( i = 0; i < xInteractionHandles.getLength(); i++ )
587 {
588 if ( xInteractionHandles[ i ].is() )
589 {
590 SdrCustomShapeInteraction aSdrCustomShapeInteraction;
591 aSdrCustomShapeInteraction.xInteraction = xInteractionHandles[ i ];
592 aSdrCustomShapeInteraction.aPosition = xInteractionHandles[ i ]->getPosition();
593
595 switch( ImpGetCustomShapeType( *this ) )
596 {
597 case mso_sptAccentBorderCallout90 : // 2 ortho
598 {
599 if (i == 0)
601 else if (i == 1)
603 }
604 break;
605
606 case mso_sptChevron :
607 case mso_sptHomePlate :
609 break;
610
615 {
616 if (i == 0)
618 }
619 break;
620
621 case mso_sptBorderCallout1 : // 2 diag
622 {
623 if (i == 0)
625 else if (i == 1)
627 }
628 break;
629 case mso_sptBorderCallout2 : // 3
630 {
631 if (i == 0)
633 else if (i == 2)
635 }
636 break;
637 case mso_sptCallout90 :
640 case mso_sptCallout1 :
641 case mso_sptCallout2 :
642 case mso_sptCallout3 :
650 {
651 if (i == 0)
653 }
654 break;
655 default: break;
656 }
657 aSdrCustomShapeInteraction.nMode = nMode;
658 aRet.push_back( aSdrCustomShapeInteraction );
659 }
660 }
661 }
662 }
663 catch( const uno::RuntimeException& )
664 {
665 }
666 return aRet;
667}
668
669
670// BaseProperties section
671#define DEFAULT_MINIMUM_SIGNED_COMPARE (sal_Int32(0x80000000))
672#define DEFAULT_MAXIMUM_SIGNED_COMPARE (sal_Int32(0x7fffffff))
673
674static sal_Int32 GetNumberOfProperties ( const SvxMSDffHandle* pData )
675{
676 sal_Int32 nPropertiesNeeded=1; // position is always needed
677 SvxMSDffHandleFlags nFlags = pData->nFlags;
678
679 if ( nFlags & SvxMSDffHandleFlags::MIRRORED_X )
680 nPropertiesNeeded++;
681 if ( nFlags & SvxMSDffHandleFlags::MIRRORED_Y )
682 nPropertiesNeeded++;
683 if ( nFlags & SvxMSDffHandleFlags::SWITCHED )
684 nPropertiesNeeded++;
685 if ( nFlags & SvxMSDffHandleFlags::POLAR )
686 {
687 nPropertiesNeeded++;
689 {
690 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
691 nPropertiesNeeded++;
692 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
693 nPropertiesNeeded++;
694 }
695 }
696 else if ( nFlags & SvxMSDffHandleFlags::RANGE )
697 {
698 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
699 nPropertiesNeeded++;
700 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
701 nPropertiesNeeded++;
702 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
703 nPropertiesNeeded++;
704 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
705 nPropertiesNeeded++;
706 }
707
708 return nPropertiesNeeded;
709}
710
711static void lcl_ShapePropertiesFromDFF( const SvxMSDffHandle* pData, beans::PropertyValues& rPropValues )
712{
713 SvxMSDffHandleFlags nFlags = pData->nFlags;
714 sal_Int32 n=0;
715 auto pPropValues = rPropValues.getArray();
716
717 // POSITION
718 {
719 drawing::EnhancedCustomShapeParameterPair aPosition;
720 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, true, true );
721 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, true, false );
722 pPropValues[ n ].Name = "Position";
723 pPropValues[ n++ ].Value <<= aPosition;
724 }
725 if ( nFlags & SvxMSDffHandleFlags::MIRRORED_X )
726 {
727 pPropValues[ n ].Name = "MirroredX";
728 pPropValues[ n++ ].Value <<= true;
729 }
730 if ( nFlags & SvxMSDffHandleFlags::MIRRORED_Y )
731 {
732 pPropValues[ n ].Name = "MirroredY";
733 pPropValues[ n++ ].Value <<= true;
734 }
735 if ( nFlags & SvxMSDffHandleFlags::SWITCHED )
736 {
737 pPropValues[ n ].Name = "Switched";
738 pPropValues[ n++ ].Value <<= true;
739 }
740 if ( nFlags & SvxMSDffHandleFlags::POLAR )
741 {
742 drawing::EnhancedCustomShapeParameterPair aCenter;
744 bool( nFlags & SvxMSDffHandleFlags::CENTER_X_IS_SPECIAL ), true );
746 bool( nFlags & SvxMSDffHandleFlags::CENTER_Y_IS_SPECIAL ), false );
747 pPropValues[ n ].Name = "Polar";
748 pPropValues[ n++ ].Value <<= aCenter;
750 {
751 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
752 {
753 drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
755 bool( nFlags & SvxMSDffHandleFlags::RANGE_X_MIN_IS_SPECIAL ), true );
756 pPropValues[ n ].Name = "RadiusRangeMinimum";
757 pPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
758 }
759 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
760 {
761 drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
763 bool( nFlags & SvxMSDffHandleFlags::RANGE_X_MAX_IS_SPECIAL ), false );
764 pPropValues[ n ].Name = "RadiusRangeMaximum";
765 pPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
766 }
767 }
768 }
769 else if ( nFlags & SvxMSDffHandleFlags::RANGE )
770 {
771 if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
772 {
773 drawing::EnhancedCustomShapeParameter aRangeXMinimum;
775 bool( nFlags & SvxMSDffHandleFlags::RANGE_X_MIN_IS_SPECIAL ), true );
776 pPropValues[ n ].Name = "RangeXMinimum";
777 pPropValues[ n++ ].Value <<= aRangeXMinimum;
778 }
779 if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
780 {
781 drawing::EnhancedCustomShapeParameter aRangeXMaximum;
783 bool( nFlags & SvxMSDffHandleFlags::RANGE_X_MAX_IS_SPECIAL ), false );
784 pPropValues[ n ].Name = "RangeXMaximum";
785 pPropValues[ n++ ].Value <<= aRangeXMaximum;
786 }
787 if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
788 {
789 drawing::EnhancedCustomShapeParameter aRangeYMinimum;
791 bool( nFlags & SvxMSDffHandleFlags::RANGE_Y_MIN_IS_SPECIAL ), true );
792 pPropValues[ n ].Name = "RangeYMinimum";
793 pPropValues[ n++ ].Value <<= aRangeYMinimum;
794 }
795 if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
796 {
797 drawing::EnhancedCustomShapeParameter aRangeYMaximum;
799 bool( nFlags & SvxMSDffHandleFlags::RANGE_Y_MAX_IS_SPECIAL ), false );
800 pPropValues[ n ].Name = "RangeYMaximum";
801 pPropValues[ n++ ].Value <<= aRangeYMaximum;
802 }
803 }
804}
805
806std::unique_ptr<sdr::properties::BaseProperties> SdrObjCustomShape::CreateObjectSpecificProperties()
807{
808 return std::make_unique<sdr::properties::CustomShapeProperties>(*this);
809}
810
812: SdrTextObj(rSdrModel)
813 , fObjectRotation(0.0)
814 , mbAdjustingTextFrameWidthAndHeight(false)
815{
816 m_bClosedObj = true; // custom shapes may be filled
817 mbTextFrame = true;
818}
819
821: SdrTextObj(rSdrModel, rSource)
822 , fObjectRotation(0.0)
823 , mbAdjustingTextFrameWidthAndHeight(false)
824{
825 m_bClosedObj = true; // custom shapes may be filled
826 mbTextFrame = true;
827
832}
833
835{
836 // delete buffered display geometry
838}
839
840void SdrObjCustomShape::MergeDefaultAttributes( const OUString* pType )
841{
842 beans::PropertyValue aPropVal;
843 OUString sShapeType;
844 static constexpr OUStringLiteral sType( u"Type" );
846 if ( pType && !pType->isEmpty() )
847 {
848 sal_Int32 nType = pType->toInt32();
849 if ( nType )
850 sShapeType = EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT >( nType ) );
851 else
852 sShapeType = *pType;
853
854 aPropVal.Name = sType;
855 aPropVal.Value <<= sShapeType;
856 aGeometryItem.SetPropertyValue( aPropVal );
857 }
858 else
859 {
860 uno::Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
861 if ( pAny )
862 *pAny >>= sShapeType;
863 }
864 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
865
866 const sal_Int32* pDefData = nullptr;
867 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
868 if ( pDefCustomShape )
869 pDefData = pDefCustomShape->pDefData;
870
871 uno::Sequence<drawing::EnhancedCustomShapeAdjustmentValue> seqAdjustmentValues;
872
873
874 // AdjustmentValues
875
876 static constexpr OUStringLiteral sAdjustmentValues( u"AdjustmentValues" );
877 const uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sAdjustmentValues );
878 if ( pAny )
879 *pAny >>= seqAdjustmentValues;
880 if ( pDefCustomShape && pDefData ) // now check if we have to default some adjustment values
881 {
882 // first check if there are adjustment values are to be appended
883 sal_Int32 i, nAdjustmentValues = seqAdjustmentValues.getLength();
884 sal_Int32 nAdjustmentDefaults = *pDefData++;
885 if ( nAdjustmentDefaults > nAdjustmentValues )
886 seqAdjustmentValues.realloc( nAdjustmentDefaults );
887 auto pseqAdjustmentValues = seqAdjustmentValues.getArray();
888 for ( i = nAdjustmentValues; i < nAdjustmentDefaults; i++ )
889 {
890 pseqAdjustmentValues[ i ].Value <<= pDefData[ i ];
891 pseqAdjustmentValues[ i ].State = beans::PropertyState_DIRECT_VALUE;
892 }
893 // check if there are defaulted adjustment values that should be filled the hard coded defaults (pDefValue)
894 sal_Int32 nCount = std::min(nAdjustmentValues, nAdjustmentDefaults);
895 for ( i = 0; i < nCount; i++ )
896 {
897 if ( seqAdjustmentValues[ i ].State != beans::PropertyState_DIRECT_VALUE )
898 {
899 pseqAdjustmentValues[ i ].Value <<= pDefData[ i ];
900 pseqAdjustmentValues[ i ].State = beans::PropertyState_DIRECT_VALUE;
901 }
902 }
903 }
904 aPropVal.Name = sAdjustmentValues;
905 aPropVal.Value <<= seqAdjustmentValues;
906 aGeometryItem.SetPropertyValue( aPropVal );
907
908
909 // Coordsize
910
911 static constexpr OUStringLiteral sViewBox( u"ViewBox" );
912 const uno::Any* pViewBox = aGeometryItem.GetPropertyValueByName( sViewBox );
913 awt::Rectangle aViewBox;
914 if ( !pViewBox || !(*pViewBox >>= aViewBox ) )
915 {
916 if ( pDefCustomShape )
917 {
918 aViewBox.X = 0;
919 aViewBox.Y = 0;
920 aViewBox.Width = pDefCustomShape->nCoordWidth;
921 aViewBox.Height= pDefCustomShape->nCoordHeight;
922 aPropVal.Name = sViewBox;
923 aPropVal.Value <<= aViewBox;
924 aGeometryItem.SetPropertyValue( aPropVal );
925 }
926 }
927
928 static constexpr OUStringLiteral sPath( u"Path" );
929
930
931 // Path/Coordinates
932
933 static constexpr OUStringLiteral sCoordinates( u"Coordinates" );
934 pAny = aGeometryItem.GetPropertyValueByName( sPath, sCoordinates );
935 if ( !pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
936 {
937 sal_Int32 i, nCount = pDefCustomShape->nVertices;
938 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqCoordinates( nCount );
939 auto pseqCoordinates = seqCoordinates.getArray();
940 for ( i = 0; i < nCount; i++ )
941 {
942 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqCoordinates[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
943 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqCoordinates[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
944 }
945 aPropVal.Name = sCoordinates;
946 aPropVal.Value <<= seqCoordinates;
947 aGeometryItem.SetPropertyValue( sPath, aPropVal );
948 }
949
950 // Path/GluePoints
951 static constexpr OUStringLiteral sGluePoints( u"GluePoints" );
952 pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePoints );
953 if ( !pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
954 {
955 sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
956 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqGluePoints( nCount );
957 auto pseqGluePoints = seqGluePoints.getArray();
958 for ( i = 0; i < nCount; i++ )
959 {
960 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqGluePoints[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
961 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqGluePoints[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
962 }
963 aPropVal.Name = sGluePoints;
964 aPropVal.Value <<= seqGluePoints;
965 aGeometryItem.SetPropertyValue( sPath, aPropVal );
966 }
967
968 // Path/Segments
969 static constexpr OUStringLiteral sSegments( u"Segments" );
970 pAny = aGeometryItem.GetPropertyValueByName( sPath, sSegments );
971 if ( !pAny && pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
972 {
973 sal_Int32 i, nCount = pDefCustomShape->nElements;
974 uno::Sequence<drawing::EnhancedCustomShapeSegment> seqSegments( nCount );
975 auto pseqSegments = seqSegments.getArray();
976 for ( i = 0; i < nCount; i++ )
977 {
978 drawing::EnhancedCustomShapeSegment& rSegInfo = pseqSegments[ i ];
979 sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
980 lcl_ShapeSegmentFromBinary( rSegInfo, nSDat );
981 }
982 aPropVal.Name = sSegments;
983 aPropVal.Value <<= seqSegments;
984 aGeometryItem.SetPropertyValue( sPath, aPropVal );
985 }
986
987 // Path/StretchX
988 static constexpr OUStringLiteral sStretchX( u"StretchX" );
989 pAny = aGeometryItem.GetPropertyValueByName( sPath, sStretchX );
990 if ( !pAny && pDefCustomShape )
991 {
992 sal_Int32 nXRef = pDefCustomShape->nXRef;
993 if ( nXRef != DEFAULT_MINIMUM_SIGNED_COMPARE )
994 {
995 aPropVal.Name = sStretchX;
996 aPropVal.Value <<= nXRef;
997 aGeometryItem.SetPropertyValue( sPath, aPropVal );
998 }
999 }
1000
1001 // Path/StretchY
1002 static constexpr OUStringLiteral sStretchY( u"StretchY" );
1003 pAny = aGeometryItem.GetPropertyValueByName( sPath, sStretchY );
1004 if ( !pAny && pDefCustomShape )
1005 {
1006 sal_Int32 nYRef = pDefCustomShape->nYRef;
1007 if ( nYRef != DEFAULT_MINIMUM_SIGNED_COMPARE )
1008 {
1009 aPropVal.Name = sStretchY;
1010 aPropVal.Value <<= nYRef;
1011 aGeometryItem.SetPropertyValue( sPath, aPropVal );
1012 }
1013 }
1014
1015 // Path/TextFrames
1016 static constexpr OUStringLiteral sTextFrames( u"TextFrames" );
1017 pAny = aGeometryItem.GetPropertyValueByName( sPath, sTextFrames );
1018 if ( !pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
1019 {
1020 sal_Int32 i, nCount = pDefCustomShape->nTextRect;
1021 uno::Sequence<drawing::EnhancedCustomShapeTextFrame> seqTextFrames( nCount );
1022 auto pseqTextFrames = seqTextFrames.getArray();
1023 const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
1024 for ( i = 0; i < nCount; i++, pRectangles++ )
1025 {
1026 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqTextFrames[ i ].TopLeft.First, pRectangles->nPairA.nValA );
1027 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqTextFrames[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
1028 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqTextFrames[ i ].BottomRight.First, pRectangles->nPairB.nValA );
1029 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqTextFrames[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
1030 }
1031 aPropVal.Name = sTextFrames;
1032 aPropVal.Value <<= seqTextFrames;
1033 aGeometryItem.SetPropertyValue( sPath, aPropVal );
1034 }
1035
1036 // Equations
1037 static constexpr OUStringLiteral sEquations( u"Equations" );
1038 pAny = aGeometryItem.GetPropertyValueByName( sEquations );
1039 if ( !pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
1040 {
1041 sal_Int32 i, nCount = pDefCustomShape->nCalculation;
1042 uno::Sequence< OUString > seqEquations( nCount );
1043 auto pseqEquations = seqEquations.getArray();
1044 const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
1045 for ( i = 0; i < nCount; i++, pData++ )
1046 pseqEquations[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
1047 aPropVal.Name = sEquations;
1048 aPropVal.Value <<= seqEquations;
1049 aGeometryItem.SetPropertyValue( aPropVal );
1050 }
1051
1052 // Handles
1053 static constexpr OUStringLiteral sHandles( u"Handles" );
1054 pAny = aGeometryItem.GetPropertyValueByName( sHandles );
1055 if ( !pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
1056 {
1057 sal_Int32 i, nCount = pDefCustomShape->nHandles;
1058 const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
1059 uno::Sequence<beans::PropertyValues> seqHandles( nCount );
1060 auto pseqHandles = seqHandles.getArray();
1061 for ( i = 0; i < nCount; i++, pData++ )
1062 {
1063 sal_Int32 nPropertiesNeeded;
1064 beans::PropertyValues& rPropValues = pseqHandles[ i ];
1065 nPropertiesNeeded = GetNumberOfProperties( pData );
1066 rPropValues.realloc( nPropertiesNeeded );
1067 lcl_ShapePropertiesFromDFF( pData, rPropValues );
1068 }
1069 aPropVal.Name = sHandles;
1070 aPropVal.Value <<= seqHandles;
1071 aGeometryItem.SetPropertyValue( aPropVal );
1072 }
1073 else if (pAny && sShapeType.startsWith("ooxml-") && sShapeType != "ooxml-non-primitive")
1074 {
1075 // ODF is not able to store the ooxml way of connecting handle to an adjustment
1076 // value by name, e.g. attribute RefX="adj". So the information is lost, when exporting
1077 // a pptx to odp, for example. This part reconstructs this information for the
1078 // ooxml preset shapes from their definition.
1079 uno::Sequence<beans::PropertyValues> seqHandles;
1080 *pAny >>= seqHandles;
1081 auto seqHandlesRange = asNonConstRange(seqHandles);
1082 bool bChanged(false);
1083 for (sal_Int32 i = 0; i < seqHandles.getLength(); i++)
1084 {
1085 comphelper::SequenceAsHashMap aHandleProps(seqHandles[i]);
1086 OUString sFirstRefType;
1087 sal_Int32 nFirstAdjRef;
1088 OUString sSecondRefType;
1089 sal_Int32 nSecondAdjRef;
1090 PresetOOXHandleAdj::GetOOXHandleAdjRelation(sShapeType, i, sFirstRefType, nFirstAdjRef,
1091 sSecondRefType, nSecondAdjRef);
1092 if (sFirstRefType != "na" && 0 <= nFirstAdjRef
1093 && nFirstAdjRef < seqAdjustmentValues.getLength())
1094 {
1095 bChanged |= aHandleProps.createItemIfMissing(sFirstRefType, nFirstAdjRef);
1096 }
1097 if (sSecondRefType != "na" && 0 <= nSecondAdjRef
1098 && nSecondAdjRef < seqAdjustmentValues.getLength())
1099 {
1100 bChanged |= aHandleProps.createItemIfMissing(sSecondRefType, nSecondAdjRef);
1101 }
1102 aHandleProps >> seqHandlesRange[i];
1103 }
1104 if (bChanged)
1105 {
1106 aPropVal.Name = sHandles;
1107 aPropVal.Value <<= seqHandles;
1108 aGeometryItem.SetPropertyValue(aPropVal);
1109 }
1110 }
1111
1112 SetMergedItem( aGeometryItem );
1113}
1114
1116{
1117 bool bIsDefaultGeometry = false;
1118
1119 OUString sShapeType;
1121
1122 const uno::Any *pAny = rGeometryItem.GetPropertyValueByName( "Type" );
1123 if ( pAny )
1124 *pAny >>= sShapeType;
1125
1126 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
1127
1128 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
1129 static constexpr OUStringLiteral sPath( u"Path" );
1130 switch( eDefaultType )
1131 {
1133 {
1134 const uno::Any* pViewBox = rGeometryItem.GetPropertyValueByName( "ViewBox" );
1135 awt::Rectangle aViewBox;
1136 if (pViewBox && (*pViewBox >>= aViewBox) && pDefCustomShape)
1137 {
1138 if ( ( aViewBox.Width == pDefCustomShape->nCoordWidth )
1139 && ( aViewBox.Height == pDefCustomShape->nCoordHeight ) )
1140 bIsDefaultGeometry = true;
1141 }
1142 }
1143 break;
1144
1145 case DefaultType::Path :
1146 {
1147 pAny = rGeometryItem.GetPropertyValueByName( sPath, "Coordinates" );
1148 if ( pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
1149 {
1150 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqCoordinates1;
1151 if ( *pAny >>= seqCoordinates1 )
1152 {
1153 sal_Int32 i, nCount = pDefCustomShape->nVertices;
1154 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqCoordinates2( nCount );
1155 auto pseqCoordinates2 = seqCoordinates2.getArray();
1156 for ( i = 0; i < nCount; i++ )
1157 {
1158 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqCoordinates2[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
1159 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqCoordinates2[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
1160 }
1161 if ( seqCoordinates1 == seqCoordinates2 )
1162 bIsDefaultGeometry = true;
1163 }
1164 }
1165 else if ( pDefCustomShape && ( ( pDefCustomShape->nVertices == 0 ) || ( pDefCustomShape->pVertices == nullptr ) ) )
1166 bIsDefaultGeometry = true;
1167 }
1168 break;
1169
1171 {
1172 pAny = rGeometryItem.GetPropertyValueByName( sPath, "GluePoints" );
1173 if ( pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
1174 {
1175 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqGluePoints1;
1176 if ( *pAny >>= seqGluePoints1 )
1177 {
1178 sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
1179 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> seqGluePoints2( nCount );
1180 auto pseqGluePoints2 = seqGluePoints2.getArray();
1181 for ( i = 0; i < nCount; i++ )
1182 {
1183 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqGluePoints2[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
1184 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqGluePoints2[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
1185 }
1186 if ( seqGluePoints1 == seqGluePoints2 )
1187 bIsDefaultGeometry = true;
1188 }
1189 }
1190 else if ( pDefCustomShape && ( pDefCustomShape->nGluePoints == 0 ) )
1191 bIsDefaultGeometry = true;
1192 }
1193 break;
1194
1196 {
1197 // Path/Segments
1198 pAny = rGeometryItem.GetPropertyValueByName( sPath, "Segments" );
1199 if ( pAny )
1200 {
1201 uno::Sequence<drawing::EnhancedCustomShapeSegment> seqSegments1;
1202 if ( *pAny >>= seqSegments1 )
1203 {
1204 if ( pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
1205 {
1206 sal_Int32 i, nCount = pDefCustomShape->nElements;
1207 if ( nCount )
1208 {
1209 uno::Sequence<drawing::EnhancedCustomShapeSegment> seqSegments2( nCount );
1210 auto pseqSegments2 = seqSegments2.getArray();
1211 for ( i = 0; i < nCount; i++ )
1212 {
1213 drawing::EnhancedCustomShapeSegment& rSegInfo = pseqSegments2[ i ];
1214 sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
1215 lcl_ShapeSegmentFromBinary( rSegInfo, nSDat );
1216 }
1217 if ( seqSegments1 == seqSegments2 )
1218 bIsDefaultGeometry = true;
1219 }
1220 }
1221 else
1222 {
1223 // check if it's the default segment description ( M L Z N )
1224 if ( seqSegments1.getLength() == 4 )
1225 {
1226 if ( ( seqSegments1[ 0 ].Command == drawing::EnhancedCustomShapeSegmentCommand::MOVETO )
1227 && ( seqSegments1[ 1 ].Command == drawing::EnhancedCustomShapeSegmentCommand::LINETO )
1228 && ( seqSegments1[ 2 ].Command == drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH )
1229 && ( seqSegments1[ 3 ].Command == drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH ) )
1230 bIsDefaultGeometry = true;
1231 }
1232 }
1233 }
1234 }
1235 else if ( pDefCustomShape && ( ( pDefCustomShape->nElements == 0 ) || ( pDefCustomShape->pElements == nullptr ) ) )
1236 bIsDefaultGeometry = true;
1237 }
1238 break;
1239
1241 {
1242 pAny = rGeometryItem.GetPropertyValueByName( sPath, "StretchX" );
1243 if ( pAny && pDefCustomShape )
1244 {
1245 sal_Int32 nStretchX = 0;
1246 if ( *pAny >>= nStretchX )
1247 {
1248 if ( pDefCustomShape->nXRef == nStretchX )
1249 bIsDefaultGeometry = true;
1250 }
1251 }
1252 else if ( pDefCustomShape && ( pDefCustomShape->nXRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1253 bIsDefaultGeometry = true;
1254 }
1255 break;
1256
1258 {
1259 pAny = rGeometryItem.GetPropertyValueByName( sPath, "StretchY" );
1260 if ( pAny && pDefCustomShape )
1261 {
1262 sal_Int32 nStretchY = 0;
1263 if ( *pAny >>= nStretchY )
1264 {
1265 if ( pDefCustomShape->nYRef == nStretchY )
1266 bIsDefaultGeometry = true;
1267 }
1268 }
1269 else if ( pDefCustomShape && ( pDefCustomShape->nYRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
1270 bIsDefaultGeometry = true;
1271 }
1272 break;
1273
1275 {
1276 pAny = rGeometryItem.GetPropertyValueByName( "Equations" );
1277 if ( pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
1278 {
1279 uno::Sequence<OUString> seqEquations1;
1280 if ( *pAny >>= seqEquations1 )
1281 {
1282 sal_Int32 i, nCount = pDefCustomShape->nCalculation;
1283 uno::Sequence<OUString> seqEquations2( nCount );
1284 auto pseqEquations2 = seqEquations2.getArray();
1285
1286 const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
1287 for ( i = 0; i < nCount; i++, pData++ )
1288 pseqEquations2[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
1289
1290 if ( seqEquations1 == seqEquations2 )
1291 bIsDefaultGeometry = true;
1292 }
1293 }
1294 else if ( pDefCustomShape && ( ( pDefCustomShape->nCalculation == 0 ) || ( pDefCustomShape->pCalculation == nullptr ) ) )
1295 bIsDefaultGeometry = true;
1296 }
1297 break;
1298
1300 {
1301 pAny = rGeometryItem.GetPropertyValueByName( sPath, "TextFrames" );
1302 if ( pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
1303 {
1304 uno::Sequence<drawing::EnhancedCustomShapeTextFrame> seqTextFrames1;
1305 if ( *pAny >>= seqTextFrames1 )
1306 {
1307 sal_Int32 i, nCount = pDefCustomShape->nTextRect;
1308 uno::Sequence<drawing::EnhancedCustomShapeTextFrame> seqTextFrames2( nCount );
1309 auto pseqTextFrames2 = seqTextFrames2.getArray();
1310 const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
1311 for ( i = 0; i < nCount; i++, pRectangles++ )
1312 {
1313 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqTextFrames2[ i ].TopLeft.First, pRectangles->nPairA.nValA );
1314 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqTextFrames2[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
1315 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqTextFrames2[ i ].BottomRight.First, pRectangles->nPairB.nValA );
1316 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( pseqTextFrames2[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
1317 }
1318 if ( seqTextFrames1 == seqTextFrames2 )
1319 bIsDefaultGeometry = true;
1320 }
1321 }
1322 else if ( pDefCustomShape && ( ( pDefCustomShape->nTextRect == 0 ) || ( pDefCustomShape->pTextRect == nullptr ) ) )
1323 bIsDefaultGeometry = true;
1324 }
1325 break;
1326 }
1327 return bIsDefaultGeometry;
1328}
1329
1331{
1333 rInfo.bResizePropAllowed=true;
1334 rInfo.bRotateFreeAllowed=true;
1335 rInfo.bRotate90Allowed =true;
1336 rInfo.bMirrorFreeAllowed=true;
1337 rInfo.bMirror45Allowed =true;
1338 rInfo.bMirror90Allowed =true;
1339 rInfo.bTransparenceAllowed = false;
1340 rInfo.bShearAllowed =true;
1341 rInfo.bEdgeRadiusAllowed=false;
1342 rInfo.bNoContortion =true;
1343
1344 // #i37011#
1345 if ( !mXRenderedCustomShape.is() )
1346 return;
1347
1348 const SdrObject* pRenderedCustomShape = SdrObject::getSdrObjectFromXShape( mXRenderedCustomShape );
1349 if ( !pRenderedCustomShape )
1350 return;
1351
1352 // #i37262#
1353 // Iterate self over the contained objects, since there are combinations of
1354 // polygon and curve objects. In that case, aInfo.bCanConvToPath and
1355 // aInfo.bCanConvToPoly would be false. What is needed here is an or, not an and.
1356 SdrObjListIter aIterator(*pRenderedCustomShape);
1357 while(aIterator.IsMore())
1358 {
1359 SdrObject* pCandidate = aIterator.Next();
1361 pCandidate->TakeObjInfo(aInfo);
1362
1363 // set path and poly conversion if one is possible since
1364 // this object will first be broken
1365 const bool bCanConvToPathOrPoly(aInfo.bCanConvToPath || aInfo.bCanConvToPoly);
1366 if(rInfo.bCanConvToPath != bCanConvToPathOrPoly)
1367 {
1368 rInfo.bCanConvToPath = bCanConvToPathOrPoly;
1369 }
1370
1371 if(rInfo.bCanConvToPoly != bCanConvToPathOrPoly)
1372 {
1373 rInfo.bCanConvToPoly = bCanConvToPathOrPoly;
1374 }
1375
1376 if(rInfo.bCanConvToContour != aInfo.bCanConvToContour)
1377 {
1379 }
1380
1381 if(rInfo.bShearAllowed != aInfo.bShearAllowed)
1382 {
1383 rInfo.bShearAllowed = aInfo.bShearAllowed;
1384 }
1385 }
1386}
1387
1389{
1391}
1392
1393// #115391# This implementation is based on the TextFrame size of the CustomShape and the
1394// state of the ResizeShapeToFitText flag to correctly set TextMinFrameWidth/Height
1396{
1397 if (getSdrModelFromSdrObject().IsCreatingDataObj() || getSdrModelFromSdrObject().IsPasteResize())
1398 return;
1399
1400 // check if we need to change anything before creating an SfxItemSet, because that is expensive
1401 const bool bResizeShapeToFitText(GetObjectItem(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue());
1402 tools::Rectangle aTextBound(getRectangle());
1403 bool bChanged(false);
1404 if(bResizeShapeToFitText)
1405 bChanged = true;
1406 else if(GetTextBounds(aTextBound))
1407 bChanged = true;
1408 if (!bChanged)
1409 return;
1410
1412 SDRATTR_TEXT_MINFRAMEWIDTH, SDRATTR_TEXT_AUTOGROWWIDTH> // contains SDRATTR_TEXT_MAXFRAMEWIDTH
1413 aSet(*GetObjectItemSet().GetPool());
1414
1415 if(bResizeShapeToFitText)
1416 {
1417 // always reset MinWidthHeight to zero to only rely on text size and frame size
1418 // to allow resizing being completely dependent on text size only
1419 aSet.Put(makeSdrTextMinFrameWidthItem(0));
1420 aSet.Put(makeSdrTextMinFrameHeightItem(0));
1421 }
1422 else
1423 {
1424 // recreate from CustomShape-specific TextBounds
1427 const tools::Long nTWdt(std::max(tools::Long(0), static_cast<tools::Long>(aTextBound.GetWidth() - 1 - nHDist)));
1428 const tools::Long nTHgt(std::max(tools::Long(0), static_cast<tools::Long>(aTextBound.GetHeight() - 1 - nVDist)));
1429
1430 aSet.Put(makeSdrTextMinFrameWidthItem(nTWdt));
1431 aSet.Put(makeSdrTextMinFrameHeightItem(nTHgt));
1432 }
1433
1434 SetObjectItemSet(aSet);
1435}
1436
1438{
1439 tools::Rectangle aRectangle(rRectangle);
1440 ImpJustifyRect(aRectangle);
1441 setRectangle(aRectangle);
1443
1445
1446 ImpCheckShear();
1448 SetChanged();
1449}
1450
1452{
1453 tools::Rectangle aBoundRect0;
1454 if ( m_pUserCall )
1455 aBoundRect0 = GetLastBoundRect();
1456 NbcSetSnapRect( rRect );
1459}
1460
1462{
1463 tools::Rectangle aRectangle(rRectangle);
1464 ImpJustifyRect(aRectangle);
1465 setRectangle(aRectangle);
1467
1469
1471 SetChanged();
1472}
1473
1475{
1476 tools::Rectangle aBoundRect0;
1477 if ( m_pUserCall )
1478 aBoundRect0 = GetLastBoundRect();
1479 NbcSetLogicRect(rRect);
1482}
1483
1485{
1486 if ( rSiz.Width() || rSiz.Height() )
1487 {
1488 tools::Rectangle aBoundRect0;
1489 if ( m_pUserCall )
1490 aBoundRect0 = GetLastBoundRect();
1491 NbcMove(rSiz);
1492 SetChanged();
1495 }
1496}
1498{
1499 SdrTextObj::NbcMove( rSiz );
1500 if ( mXRenderedCustomShape.is() )
1501 {
1503 if ( pRenderedCustomShape )
1504 {
1505 // #i97149# the visualisation shape needs to be informed
1506 // about change, too
1507 pRenderedCustomShape->ActionChanged();
1508 pRenderedCustomShape->NbcMove( rSiz );
1509 }
1510 }
1511
1512 // #i37011# adapt geometry shadow
1514 {
1515 mpLastShadowGeometry->NbcMove( rSiz );
1516 }
1517}
1518
1519void SdrObjCustomShape::NbcResize( const Point& rRef, const Fraction& rxFact, const Fraction& ryFact )
1520{
1521 // taking care of handles that should not been changed
1523 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles() );
1524
1525 SdrTextObj::NbcResize( rRef, rxFact, ryFact );
1526
1527 if ( ( rxFact.GetNumerator() != rxFact.GetDenominator() )
1528 || ( ryFact.GetNumerator()!= ryFact.GetDenominator() ) )
1529 {
1530 if ( ( ( rxFact.GetNumerator() < 0 ) && ( rxFact.GetDenominator() > 0 ) ) ||
1531 ( ( rxFact.GetNumerator() > 0 ) && ( rxFact.GetDenominator() < 0 ) ) )
1532 {
1534 }
1535 if ( ( ( ryFact.GetNumerator() < 0 ) && ( ryFact.GetDenominator() > 0 ) ) ||
1536 ( ( ryFact.GetNumerator() > 0 ) && ( ryFact.GetDenominator() < 0 ) ) )
1537 {
1539 }
1540 }
1541
1542 for (const auto& rInteraction : aInteractionHandles)
1543 {
1544 try
1545 {
1546 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_FIXED )
1547 rInteraction.xInteraction->setControllerPosition( rInteraction.aPosition );
1548 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_ABSOLUTE_X )
1549 {
1550 sal_Int32 nX = ( rInteraction.aPosition.X - aOld.Left() ) + getRectangle().Left();
1551 rInteraction.xInteraction->setControllerPosition(awt::Point(nX, rInteraction.xInteraction->getPosition().Y));
1552 }
1553 else if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_ABSOLUTE_NEGX )
1554 {
1555 sal_Int32 nX = getRectangle().Right() - (aOld.Right() - rInteraction.aPosition.X);
1556 rInteraction.xInteraction->setControllerPosition(awt::Point(nX, rInteraction.xInteraction->getPosition().Y));
1557 }
1558 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_ABSOLUTE_Y )
1559 {
1560 sal_Int32 nY = ( rInteraction.aPosition.Y - aOld.Top() ) + getRectangle().Top();
1561 rInteraction.xInteraction->setControllerPosition(awt::Point(rInteraction.xInteraction->getPosition().X, nY));
1562 }
1563 }
1564 catch ( const uno::RuntimeException& )
1565 {
1566 }
1567 }
1568
1569 // updating fObjectRotation
1570 Degree100 nTextObjRotation = maGeo.m_nRotationAngle;
1571 double fAngle = toDegrees(nTextObjRotation);
1572 if (IsMirroredX())
1573 {
1574 if (IsMirroredY())
1575 fObjectRotation = fAngle - 180.0;
1576 else
1577 fObjectRotation = -fAngle;
1578 }
1579 else
1580 {
1581 if (IsMirroredY())
1582 fObjectRotation = 180.0 - fAngle;
1583 else
1584 fObjectRotation = fAngle;
1585 }
1586 while (fObjectRotation < 0)
1587 fObjectRotation += 360.0;
1588 while (fObjectRotation >= 360.0)
1589 fObjectRotation -= 360.0;
1590
1592}
1593
1594void SdrObjCustomShape::NbcRotate( const Point& rRef, Degree100 nAngle, double sn, double cs )
1595{
1596 bool bMirroredX = IsMirroredX();
1597 bool bMirroredY = IsMirroredY();
1598
1599 fObjectRotation = fmod( fObjectRotation, 360.0 );
1600 if ( fObjectRotation < 0 )
1602
1603 // the rotation angle for ashapes is stored in fObjectRotation, this rotation
1604 // has to be applied to the text object (which is internally using maGeo.nAngle).
1605 SdrTextObj::NbcRotate( getRectangle().TopLeft(), -maGeo.m_nRotationAngle, // retrieving the unrotated text object
1608 maGeo.m_nRotationAngle = 0_deg100; // resetting aGeo data
1610
1611 Degree100 nW(static_cast<sal_Int32>( fObjectRotation * 100 )); // applying our object rotation
1612 if ( bMirroredX )
1613 nW = 36000_deg100 - nW;
1614 if ( bMirroredY )
1615 nW = 18000_deg100 - nW;
1616 nW = nW % 36000_deg100;
1617 if ( nW < 0_deg100 )
1618 nW = 36000_deg100 + nW;
1619 SdrTextObj::NbcRotate( getRectangle().TopLeft(), nW, // applying text rotation
1620 sin( toRadians(nW) ),
1621 cos( toRadians(nW) ) );
1622
1623 int nSwap = 0;
1624 if ( bMirroredX )
1625 nSwap ^= 1;
1626 if ( bMirroredY )
1627 nSwap ^= 1;
1628
1629 double fAngle = toDegrees(nAngle); // updating to our new object rotation
1630 fObjectRotation = fmod( nSwap ? fObjectRotation - fAngle : fObjectRotation + fAngle, 360.0 );
1631 if ( fObjectRotation < 0 )
1633
1634 SdrTextObj::NbcRotate( rRef, nAngle, sn, cs ); // applying text rotation
1636}
1637
1638void SdrObjCustomShape::NbcMirror( const Point& rRef1, const Point& rRef2 )
1639{
1640 // TTTT: Fix for old mirroring, can be removed again in aw080
1641 // storing horizontal and vertical flipping without modifying the rotate angle
1642 // decompose other flipping to rotation and MirrorX.
1643 tools::Long ndx = rRef2.X()-rRef1.X();
1644 tools::Long ndy = rRef2.Y()-rRef1.Y();
1645
1646 if(!ndx) // MirroredX
1647 {
1649 SdrTextObj::NbcMirror( rRef1, rRef2 );
1650 }
1651 else
1652 {
1653 if(!ndy) // MirroredY
1654 {
1656 SdrTextObj::NbcMirror( rRef1, rRef2 );
1657 }
1658 else // neither horizontal nor vertical
1659 {
1661
1662 // call parent
1663 SdrTextObj::NbcMirror( rRef1, rRef2 );
1664
1665 // update fObjectRotation
1666 Degree100 nTextObjRotation = maGeo.m_nRotationAngle;
1667 double fAngle = toDegrees(nTextObjRotation);
1668
1669 bool bSingleFlip = (IsMirroredX()!= IsMirroredY());
1670
1671 fObjectRotation = fmod( bSingleFlip ? -fAngle : fAngle, 360.0 );
1672
1673 if ( fObjectRotation < 0 )
1674 {
1676 }
1677 }
1678 }
1679
1681}
1682
1683void SdrObjCustomShape::Shear( const Point& rRef, Degree100 nAngle, double tn, bool bVShear )
1684{
1685 SdrTextObj::Shear( rRef, nAngle, tn, bVShear );
1687}
1688void SdrObjCustomShape::NbcShear( const Point& rRef, Degree100 nAngle, double tn, bool bVShear )
1689{
1690 // TTTT: Fix for old mirroring, can be removed again in aw080
1691 SdrTextObj::NbcShear(rRef,nAngle,tn,bVShear);
1692
1693 // updating fObjectRotation
1694 Degree100 nTextObjRotation = maGeo.m_nRotationAngle;
1695 double fAngle = toDegrees(nTextObjRotation);
1696 if (IsMirroredX())
1697 {
1698 if (IsMirroredY())
1699 fObjectRotation = fAngle - 180.0;
1700 else
1701 fObjectRotation = -fAngle;
1702 }
1703 else
1704 {
1705 if (IsMirroredY())
1706 fObjectRotation = 180.0 - fAngle;
1707 else
1708 fObjectRotation = fAngle;
1709 }
1710 while (fObjectRotation < 0)
1711 fObjectRotation += 360.0;
1712 while (fObjectRotation >= 360.0)
1713 fObjectRotation -= 360.0;
1714
1716}
1717
1719{
1720 sal_Int32 nWdt = ImpGetLineWdt(); // #i25616#
1721
1722 // #i25616#
1724 {
1725 nWdt++;
1726 nWdt /= 2;
1727 }
1728
1729 Point aPt;
1730 auto aRectangle = getRectangle();
1731 switch (nPosNum)
1732 {
1733 case 0: aPt = aRectangle.TopCenter(); aPt.AdjustY( -nWdt ); break;
1734 case 1: aPt = aRectangle.RightCenter(); aPt.AdjustX(nWdt ); break;
1735 case 2: aPt = aRectangle.BottomCenter(); aPt.AdjustY(nWdt ); break;
1736 case 3: aPt = aRectangle.LeftCenter(); aPt.AdjustX( -nWdt ); break;
1737 }
1738 if (maGeo.m_nShearAngle != 0_deg100)
1739 ShearPoint(aPt, aRectangle.TopLeft(), maGeo.mfTanShearAngle);
1740 if (maGeo.m_nRotationAngle != 0_deg100)
1741 RotatePoint(aPt, aRectangle.TopLeft(), maGeo.mfSinRotationAngle, maGeo.mfCosRotationAngle);
1742 aPt-=GetSnapRect().Center();
1743 SdrGluePoint aGP(aPt);
1744 aGP.SetPercent(false);
1745 return aGP;
1746}
1747
1748
1749// #i38892#
1751{
1752 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
1753
1754 if(!pSdrObject)
1755 return;
1756
1757 const SdrGluePointList* pSource = pSdrObject->GetGluePointList();
1758
1759 if(!(pSource && pSource->GetCount()))
1760 return;
1761
1763 {
1765 }
1766
1768
1769 if(!pList)
1770 return;
1771
1772 SdrGluePointList aNewList;
1773 sal_uInt16 a;
1774
1775 for(a = 0; a < pSource->GetCount(); a++)
1776 {
1777 SdrGluePoint aCopy((*pSource)[a]);
1778 aCopy.SetUserDefined(false);
1779 aNewList.Insert(aCopy);
1780 }
1781
1782 bool bMirroredX = IsMirroredX();
1783 bool bMirroredY = IsMirroredY();
1784
1785 Degree100 nShearAngle = maGeo.m_nShearAngle;
1786 double fTan = maGeo.mfTanShearAngle;
1787
1788 if (maGeo.m_nRotationAngle || nShearAngle || bMirroredX || bMirroredY)
1789 {
1791 if( nShearAngle )
1792 {
1793 sal_uInt16 nPointCount=aPoly.GetSize();
1794 for (sal_uInt16 i=0; i<nPointCount; i++)
1795 ShearPoint(aPoly[i], getRectangle().Center(), fTan );
1796 }
1798 aPoly.Rotate( getRectangle().Center(), to<Degree10>(maGeo.m_nRotationAngle) );
1799
1800 tools::Rectangle aBoundRect( aPoly.GetBoundRect() );
1801 sal_Int32 nXDiff = aBoundRect.Left() - getRectangle().Left();
1802 sal_Int32 nYDiff = aBoundRect.Top() - getRectangle().Top();
1803
1804 if (nShearAngle && bMirroredX != bMirroredY)
1805 {
1806 nShearAngle = -nShearAngle;
1807 fTan = -fTan;
1808 }
1809
1810 Point aRef( getRectangle().GetWidth() / 2, getRectangle().GetHeight() / 2 );
1811 for ( a = 0; a < aNewList.GetCount(); a++ )
1812 {
1813 SdrGluePoint& rPoint = aNewList[ a ];
1814 Point aGlue( rPoint.GetPos() );
1815 if ( nShearAngle )
1816 ShearPoint( aGlue, aRef, fTan );
1817
1818 RotatePoint(aGlue, aRef, sin(basegfx::deg2rad(fObjectRotation)),
1820 if ( bMirroredX )
1821 aGlue.setX( getRectangle().GetWidth() - aGlue.X() );
1822 if ( bMirroredY )
1823 aGlue.setY( getRectangle().GetHeight() - aGlue.Y() );
1824 aGlue.AdjustX( -nXDiff );
1825 aGlue.AdjustY( -nYDiff );
1826 rPoint.SetPos( aGlue );
1827 }
1828 }
1829
1830 for(a = 0; a < pList->GetCount(); a++)
1831 {
1832 const SdrGluePoint& rCandidate = (*pList)[a];
1833
1834 if(rCandidate.IsUserDefined())
1835 {
1836 aNewList.Insert(rCandidate);
1837 }
1838 }
1839
1840 // copy new list to local. This is NOT very convenient behavior, the local
1841 // GluePointList should not be set, but we delivered by using GetGluePointList(),
1842 // maybe on demand. Since the local object is changed here, this is assumed to
1843 // be a result of GetGluePointList and thus the list is copied
1844 if(m_pPlusData)
1845 {
1846 m_pPlusData->SetGluePoints(aNewList);
1847 }
1848}
1849
1850// #i38892#
1852{
1855}
1856
1857// #i38892#
1859{
1861 {
1864 }
1865 else
1866 {
1867 return nullptr;
1868 }
1869}
1870
1871
1873{
1874 const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
1875 return ( GetInteractionHandles().size() + nBasicHdlCount );
1876}
1877
1879{
1880 SdrTextObj::AddToHdlList(rHdlList);
1881
1882 int nCustomShapeHdlNum = 0;
1883 for (SdrCustomShapeInteraction const & rInteraction : GetInteractionHandles())
1884 {
1885 if ( rInteraction.xInteraction.is() )
1886 {
1887 try
1888 {
1889 awt::Point aPosition( rInteraction.xInteraction->getPosition() );
1890 std::unique_ptr<SdrHdl> pH(new SdrHdl( Point( aPosition.X, aPosition.Y ), SdrHdlKind::CustomShape1 ));
1891 pH->SetPointNum( nCustomShapeHdlNum );
1892 pH->SetObj( const_cast<SdrObjCustomShape*>(this) );
1893 rHdlList.AddHdl(std::move(pH));
1894 }
1895 catch ( const uno::RuntimeException& )
1896 {
1897 }
1898 }
1899 ++nCustomShapeHdlNum;
1900 }
1901}
1902
1904{
1905 return true;
1906}
1907
1909{
1910 const SdrHdl* pHdl = rDrag.GetHdl();
1911
1912 if(pHdl && SdrHdlKind::CustomShape1 == pHdl->GetKind())
1913 {
1914 rDrag.SetEndDragChangesAttributes(true);
1915 rDrag.SetNoSnap();
1916 }
1917 else
1918 {
1919 const SdrHdl* pHdl2 = rDrag.GetHdl();
1920 const SdrHdlKind eHdl((pHdl2 == nullptr) ? SdrHdlKind::Move : pHdl2->GetKind());
1921
1922 switch( eHdl )
1923 {
1925 case SdrHdlKind::Upper :
1927 case SdrHdlKind::Left :
1928 case SdrHdlKind::Right :
1930 case SdrHdlKind::Lower :
1932 case SdrHdlKind::Move :
1933 {
1934 break;
1935 }
1936 default:
1937 {
1938 return false;
1939 }
1940 }
1941 }
1942
1943 return true;
1944}
1945
1947{
1949 bool bOldMirroredX( IsMirroredX() );
1950 bool bOldMirroredY( IsMirroredY() );
1951
1952 tools::Rectangle aNewRect( rNewRect );
1953 aNewRect.Normalize();
1954
1955 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles() );
1956
1957 GeoStat aGeoStat( GetGeoStat() );
1958 if ( aNewRect.TopLeft() != getRectangle().TopLeft() &&
1960 {
1961 Point aNewPos( aNewRect.TopLeft() );
1962 if ( maGeo.m_nShearAngle ) ShearPoint( aNewPos, aOld.TopLeft(), aGeoStat.mfTanShearAngle );
1963 if ( maGeo.m_nRotationAngle ) RotatePoint(aNewPos, aOld.TopLeft(), aGeoStat.mfSinRotationAngle, aGeoStat.mfCosRotationAngle );
1964 aNewRect.SetPos( aNewPos );
1965 }
1966 if (aNewRect == getRectangle())
1967 return;
1968
1969 SetLogicRect( aNewRect );
1971
1972 if ( rNewRect.Left() > rNewRect.Right() )
1973 {
1974 Point aTop( ( GetSnapRect().Left() + GetSnapRect().Right() ) >> 1, GetSnapRect().Top() );
1975 Point aBottom( aTop.X(), aTop.Y() + 1000 );
1976 NbcMirror( aTop, aBottom );
1977 }
1978 if ( rNewRect.Top() > rNewRect.Bottom() )
1979 {
1980 Point aLeft( GetSnapRect().Left(), ( GetSnapRect().Top() + GetSnapRect().Bottom() ) >> 1 );
1981 Point aRight( aLeft.X() + 1000, aLeft.Y() );
1982 NbcMirror( aLeft, aRight );
1983 }
1984
1985 for (const auto& rInteraction : aInteractionHandles)
1986 {
1987 try
1988 {
1989 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_FIXED )
1990 rInteraction.xInteraction->setControllerPosition( rInteraction.aPosition );
1991 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_ABSOLUTE_X ||
1993 {
1994 if (rInteraction.nMode & CustomShapeHandleModes::RESIZE_ABSOLUTE_NEGX)
1995 bOldMirroredX = !bOldMirroredX;
1996
1997 sal_Int32 nX;
1998 if ( bOldMirroredX )
1999 {
2000 nX = ( rInteraction.aPosition.X - aOld.Right() );
2001 if ( rNewRect.Left() > rNewRect.Right() )
2002 nX = getRectangle().Left() - nX;
2003 else
2004 nX += getRectangle().Right();
2005 }
2006 else
2007 {
2008 nX = ( rInteraction.aPosition.X - aOld.Left() );
2009 if ( rNewRect.Left() > rNewRect.Right() )
2010 nX = getRectangle().Right() - nX;
2011 else
2012 nX += getRectangle().Left();
2013 }
2014 rInteraction.xInteraction->setControllerPosition(awt::Point(nX, rInteraction.xInteraction->getPosition().Y));
2015 }
2016 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_ABSOLUTE_Y )
2017 {
2018 sal_Int32 nY;
2019 if ( bOldMirroredY )
2020 {
2021 nY = ( rInteraction.aPosition.Y - aOld.Bottom() );
2022 if ( rNewRect.Top() > rNewRect.Bottom() )
2023 nY = getRectangle().Top() - nY;
2024 else
2025 nY += getRectangle().Bottom();
2026 }
2027 else
2028 {
2029 nY = ( rInteraction.aPosition.Y - aOld.Top() );
2030 if ( rNewRect.Top() > rNewRect.Bottom() )
2031 nY = getRectangle().Bottom() - nY;
2032 else
2033 nY += getRectangle().Top();
2034 }
2035 rInteraction.xInteraction->setControllerPosition(awt::Point(rInteraction.xInteraction->getPosition().X, nY));
2036 }
2037 }
2038 catch ( const uno::RuntimeException& )
2039 {
2040 }
2041 }
2042}
2043
2045 const sal_uInt16 nCustomShapeHdlNum, bool bMoveCalloutRectangle )
2046{
2047 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles() );
2048 if ( nCustomShapeHdlNum >= aInteractionHandles.size() )
2049 return;
2050
2051 SdrCustomShapeInteraction aInteractionHandle( aInteractionHandles[ nCustomShapeHdlNum ] );
2052 if ( !aInteractionHandle.xInteraction.is() )
2053 return;
2054
2055 try
2056 {
2057 awt::Point aPt( rDestination.X(), rDestination.Y() );
2058 if ( aInteractionHandle.nMode & CustomShapeHandleModes::MOVE_SHAPE && bMoveCalloutRectangle )
2059 {
2060 sal_Int32 nXDiff = aPt.X - aInteractionHandle.aPosition.X;
2061 sal_Int32 nYDiff = aPt.Y - aInteractionHandle.aPosition.Y;
2062
2063 moveRectangle(nXDiff, nYDiff);
2064 moveOutRectangle(nXDiff, nYDiff);
2065 maSnapRect.Move( nXDiff, nYDiff );
2066 SetBoundAndSnapRectsDirty(/*bNotMyself*/true);
2068
2069 for (const auto& rInteraction : aInteractionHandles)
2070 {
2071 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_FIXED )
2072 {
2073 if ( rInteraction.xInteraction.is() )
2074 rInteraction.xInteraction->setControllerPosition( rInteraction.aPosition );
2075 }
2076 }
2077 }
2078 aInteractionHandle.xInteraction->setControllerPosition( aPt );
2079 }
2080 catch ( const uno::RuntimeException& )
2081 {
2082 }
2083}
2084
2086{
2087 const SdrHdl* pHdl = rDrag.GetHdl();
2088 const SdrHdlKind eHdl((pHdl == nullptr) ? SdrHdlKind::Move : pHdl->GetKind());
2089
2090 switch(eHdl)
2091 {
2093 {
2095 DragMoveCustomShapeHdl( rDrag.GetNow(), static_cast<sal_uInt16>(pHdl->GetPointNum()), !rDrag.GetDragMethod()->IsShiftPressed() );
2098 SetChanged();
2099 break;
2100 }
2101
2103 case SdrHdlKind::Upper :
2105 case SdrHdlKind::Left :
2106 case SdrHdlKind::Right :
2108 case SdrHdlKind::Lower :
2110 {
2112 break;
2113 }
2114 case SdrHdlKind::Move :
2115 {
2116 Move(Size(rDrag.GetDX(), rDrag.GetDY()));
2117 break;
2118 }
2119 default: break;
2120 }
2121
2122 return true;
2123}
2124
2125
2127{
2128 tools::Rectangle aRect1;
2129 rStat.TakeCreateRect( aRect1 );
2130
2131 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles() );
2132
2133 constexpr sal_uInt32 nDefaultObjectSizeWidth = 3000; // default width from SDOptions ?
2134 constexpr sal_uInt32 nDefaultObjectSizeHeight= 3000;
2135
2136 if ( ImpVerticalSwitch( *this ) )
2137 {
2138 SetMirroredX( aRect1.Left() > aRect1.Right() );
2139
2140 aRect1 = tools::Rectangle( rStat.GetNow(), Size( nDefaultObjectSizeWidth, nDefaultObjectSizeHeight ) );
2141 // subtracting the horizontal difference of the latest handle from shape position
2142 if ( !aInteractionHandles.empty() )
2143 {
2144 sal_Int32 nHandlePos = aInteractionHandles[ aInteractionHandles.size() - 1 ].xInteraction->getPosition().X;
2145 aRect1.Move(getRectangle().Left() - nHandlePos, 0);
2146 }
2147 }
2148 ImpJustifyRect( aRect1 );
2149 rStat.SetActionRect( aRect1 );
2150 setRectangle(aRect1);
2152
2153 for (const auto& rInteraction : aInteractionHandles)
2154 {
2155 try
2156 {
2157 if ( rInteraction.nMode & CustomShapeHandleModes::CREATE_FIXED )
2158 rInteraction.xInteraction->setControllerPosition( awt::Point( rStat.GetStart().X(), rStat.GetStart().Y() ) );
2159 }
2160 catch ( const uno::RuntimeException& )
2161 {
2162 }
2163 }
2164
2166 m_bSnapRectDirty=true;
2167}
2168
2170{
2171 SdrView* pView = rStat.GetView(); // #i37448#
2172 if( pView && pView->IsSolidDragging() )
2173 {
2175 }
2176 DragCreateObject( rStat );
2178 return true;
2179}
2180
2182{
2183 DragCreateObject( rStat );
2184
2186
2188 return ( eCmd == SdrCreateCmd::ForceEnd || rStat.GetPointCount() >= 2 );
2189}
2190
2192{
2193 return GetLineGeometry( false );
2194}
2195
2196
2197// in context with the SdrObjCustomShape the SdrTextAutoGrowHeightItem == true -> Resize Shape to fit text,
2198// the SdrTextAutoGrowWidthItem == true -> Word wrap text in Shape
2200{
2201 const SfxItemSet& rSet = GetMergedItemSet();
2202 bool bIsAutoGrowHeight = rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue();
2203 if ( bIsAutoGrowHeight && IsVerticalWriting() )
2204 bIsAutoGrowHeight = !rSet.Get(SDRATTR_TEXT_WORDWRAP).GetValue();
2205 return bIsAutoGrowHeight;
2206}
2208{
2209 const SfxItemSet& rSet = GetMergedItemSet();
2210 bool bIsAutoGrowWidth = rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue();
2211 if ( bIsAutoGrowWidth && !IsVerticalWriting() )
2212 bIsAutoGrowWidth = !rSet.Get(SDRATTR_TEXT_WORDWRAP).GetValue();
2213 return bIsAutoGrowWidth;
2214}
2215
2216/* The following method is identical to the SdrTextObj::SetVerticalWriting method, the only difference
2217 is that the SdrAutoGrowWidthItem and SdrAutoGrowHeightItem are not exchanged if the vertical writing
2218 mode has been changed */
2219
2221{
2223
2224 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2225
2226 DBG_ASSERT( pOutlinerParaObject, "SdrTextObj::SetVerticalWriting() without OutlinerParaObject!" );
2227
2228 if( !pOutlinerParaObject ||
2229 (pOutlinerParaObject->IsEffectivelyVertical() == bVertical) )
2230 return;
2231
2232 // get item settings
2233 const SfxItemSet& rSet = GetObjectItemSet();
2234
2235 // Also exchange horizontal and vertical adjust items
2238
2239 // rescue object size, SetSnapRect below expects logic rect,
2240 // not snap rect.
2241 tools::Rectangle aObjectRect = GetLogicRect();
2242
2243 // prepare ItemSet to set exchanged width and height items
2245 // Expanded item ranges to also support horizontal and vertical adjust.
2248
2249 aNewSet.Put(rSet);
2250
2251 // Exchange horizontal and vertical adjusts
2252 switch(eVert)
2253 {
2258 }
2259 switch(eHorz)
2260 {
2265 }
2266
2267 pOutlinerParaObject = GetOutlinerParaObject();
2268 if ( pOutlinerParaObject )
2269 pOutlinerParaObject->SetVertical(bVertical);
2270 SetObjectItemSet( aNewSet );
2271
2272 // restore object size
2273 SetSnapRect(aObjectRect);
2274}
2275
2277{
2278 m_aSuggestedTextFrameSize = aSuggestedTextFrameSize;
2279}
2280
2282{
2283 // Either we have text or the application has native text and suggested its size to us.
2284 bool bHasText = HasText() || !m_aSuggestedTextFrameSize.IsEmpty();
2285 if ( bHasText && !rR.IsEmpty() )
2286 {
2287 bool bWdtGrow=bWdt && IsAutoGrowWidth();
2288 bool bHgtGrow=bHgt && IsAutoGrowHeight();
2289 if ( bWdtGrow || bHgtGrow )
2290 {
2291 tools::Rectangle aR0(rR);
2292 tools::Long nHgt=0,nMinHgt=0,nMaxHgt=0;
2293 tools::Long nWdt=0,nMinWdt=0,nMaxWdt=0;
2294 Size aSiz(rR.GetSize()); aSiz.AdjustWidth( -1 ); aSiz.AdjustHeight( -1 );
2295 Size aMaxSiz(100000,100000);
2296 Size aTmpSiz(getSdrModelFromSdrObject().GetMaxObjSize());
2297 if (aTmpSiz.Width()!=0) aMaxSiz.setWidth(aTmpSiz.Width() );
2298 if (aTmpSiz.Height()!=0) aMaxSiz.setHeight(aTmpSiz.Height() );
2299 if (bWdtGrow)
2300 {
2301 nMinWdt=GetMinTextFrameWidth();
2302 nMaxWdt=GetMaxTextFrameWidth();
2303 if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
2304 if (nMinWdt<=0) nMinWdt=1;
2305 aSiz.setWidth(nMaxWdt );
2306 }
2307 if (bHgtGrow)
2308 {
2309 nMinHgt=GetMinTextFrameHeight();
2310 nMaxHgt=GetMaxTextFrameHeight();
2311 if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
2312 if (nMinHgt<=0) nMinHgt=1;
2313 aSiz.setHeight(nMaxHgt );
2314 }
2317 aSiz.AdjustWidth( -nHDist );
2318 aSiz.AdjustHeight( -nVDist );
2319 if ( aSiz.Width() < 2 )
2320 aSiz.setWidth( 2 ); // minimum size=2
2321 if ( aSiz.Height() < 2 )
2322 aSiz.setHeight( 2 ); // minimum size=2
2323
2324 if (HasText())
2325 {
2327 {
2329 if (bWdtGrow)
2330 {
2332 nWdt=aSiz2.Width()+1; // a little more tolerance
2333 if (bHgtGrow) nHgt=aSiz2.Height()+1; // a little more tolerance
2334 } else
2335 {
2336 nHgt=mpEditingOutliner->GetTextHeight()+1; // a little more tolerance
2337 }
2338 }
2339 else
2340 {
2341 Outliner& rOutliner=ImpGetDrawOutliner();
2342 rOutliner.SetPaperSize(aSiz);
2343 rOutliner.SetUpdateLayout(true);
2344 // TODO: add the optimization with bPortionInfoChecked again.
2345 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
2346 if( pOutlinerParaObject != nullptr )
2347 {
2348 rOutliner.SetText(*pOutlinerParaObject);
2350 }
2351 if ( bWdtGrow )
2352 {
2353 Size aSiz2(rOutliner.CalcTextSize());
2354 nWdt=aSiz2.Width()+1; // a little more tolerance
2355 if ( bHgtGrow )
2356 nHgt=aSiz2.Height()+1; // a little more tolerance
2357 }
2358 else
2359 {
2360 nHgt = rOutliner.GetTextHeight()+1; // a little more tolerance
2361
2362 sal_Int16 nColumns = GetMergedItem(SDRATTR_TEXTCOLUMNS_NUMBER).GetValue();
2363 if (bHgtGrow && nColumns > 1)
2364 {
2365 // Both 'resize shape to fix text' and multiple columns are enabled. The
2366 // first means a dynamic height, the second expects a fixed height.
2367 // Resolve this conflict by going with the original height.
2368 nHgt = rR.getOpenHeight();
2369 }
2370 }
2371 rOutliner.Clear();
2372 }
2373 }
2374 else
2375 {
2378 }
2379 if ( nWdt < nMinWdt )
2380 nWdt = nMinWdt;
2381 if ( nWdt > nMaxWdt )
2382 nWdt = nMaxWdt;
2383 nWdt += nHDist;
2384 if ( nWdt < 1 )
2385 nWdt = 1; // nHDist may also be negative
2386 if ( nHgt < nMinHgt )
2387 nHgt = nMinHgt;
2388 if ( nHgt > nMaxHgt )
2389 nHgt = nMaxHgt;
2390 nHgt+=nVDist;
2391 if ( nHgt < 1 )
2392 nHgt = 1; // nVDist may also be negative
2393 tools::Long nWdtGrow = nWdt-(rR.Right()-rR.Left());
2394 tools::Long nHgtGrow = nHgt-(rR.Bottom()-rR.Top());
2395 if ( nWdtGrow == 0 )
2396 bWdtGrow = false;
2397 if ( nHgtGrow == 0 )
2398 bHgtGrow=false;
2399 if ( bWdtGrow || bHgtGrow || !m_aSuggestedTextFrameSize.IsEmpty())
2400 {
2401 if ( bWdtGrow || m_aSuggestedTextFrameSize.Width() )
2402 {
2405 {
2407 }
2408 else if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2409 rR.AdjustRight(nWdtGrow );
2410 else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2411 rR.AdjustLeft( -nWdtGrow );
2412 else
2413 {
2414 tools::Long nWdtGrow2=nWdtGrow/2;
2415 rR.AdjustLeft( -nWdtGrow2 );
2416 rR.SetRight(rR.Left()+nWdt );
2417 }
2418 }
2419 if ( bHgtGrow || m_aSuggestedTextFrameSize.Height() )
2420 {
2423 {
2425 }
2426 else if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2427 rR.AdjustBottom(nHgtGrow );
2428 else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2429 rR.AdjustTop( -nHgtGrow );
2430 else
2431 {
2432 tools::Long nHgtGrow2=nHgtGrow/2;
2433 rR.AdjustTop( -nHgtGrow2 );
2434 rR.SetBottom(rR.Top()+nHgt );
2435 }
2436 }
2437 if ( maGeo.m_nRotationAngle )
2438 {
2439 Point aD1(rR.TopLeft());
2440 aD1-=aR0.TopLeft();
2441 Point aD2(aD1);
2443 aD2-=aD1;
2444 rR.Move(aD2.X(),aD2.Y());
2445 }
2446 return true;
2447 }
2448 }
2449 }
2450 return false;
2451}
2452
2454{
2455 tools::Rectangle aReturnValue;
2456
2457 tools::Rectangle aOldTextRect(getRectangle()); // <- initial text rectangle
2458
2459 tools::Rectangle aNewTextRect(getRectangle()); // <- new text rectangle returned from the custom shape renderer,
2460 GetTextBounds( aNewTextRect ); // it depends to the current logical shape size
2461
2462 tools::Rectangle aAdjustedTextRect( aNewTextRect ); // <- new text rectangle is being tested by AdjustTextFrameWidthAndHeight to ensure
2463 if ( AdjustTextFrameWidthAndHeight( aAdjustedTextRect, bHgt, bWdt ) ) // that the new text rectangle is matching the current text size from the outliner
2464 {
2465 if (aAdjustedTextRect != aNewTextRect && aOldTextRect != aAdjustedTextRect &&
2466 aNewTextRect.GetWidth() && aNewTextRect.GetHeight())
2467 {
2468 aReturnValue = getRectangle();
2469 double fXScale = static_cast<double>(aOldTextRect.GetWidth()) / static_cast<double>(aNewTextRect.GetWidth());
2470 double fYScale = static_cast<double>(aOldTextRect.GetHeight()) / static_cast<double>(aNewTextRect.GetHeight());
2471 double fRightDiff = static_cast<double>( aAdjustedTextRect.Right() - aNewTextRect.Right() ) * fXScale;
2472 double fLeftDiff = static_cast<double>( aAdjustedTextRect.Left() - aNewTextRect.Left() ) * fXScale;
2473 double fTopDiff = static_cast<double>( aAdjustedTextRect.Top() - aNewTextRect.Top() ) * fYScale;
2474 double fBottomDiff= static_cast<double>( aAdjustedTextRect.Bottom()- aNewTextRect.Bottom()) * fYScale;
2475 aReturnValue.AdjustLeft(static_cast<sal_Int32>(fLeftDiff) );
2476 aReturnValue.AdjustRight(static_cast<sal_Int32>(fRightDiff) );
2477 aReturnValue.AdjustTop(static_cast<sal_Int32>(fTopDiff) );
2478 aReturnValue.AdjustBottom(static_cast<sal_Int32>(fBottomDiff) );
2479 }
2480 }
2481 return aReturnValue;
2482}
2483
2485{
2486 tools::Rectangle aNewTextRect = ImpCalculateTextFrame(bHgt, bWdt);
2487 const bool bRet = !aNewTextRect.IsEmpty() && aNewTextRect != getRectangle();
2489 {
2491
2492 // taking care of handles that should not been changed
2493 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles() );
2494
2495 setRectangle(aNewTextRect);
2497 SetChanged();
2498
2499 for (const auto& rInteraction : aInteractionHandles)
2500 {
2501 try
2502 {
2503 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_FIXED )
2504 rInteraction.xInteraction->setControllerPosition( rInteraction.aPosition );
2505 }
2506 catch ( const uno::RuntimeException& )
2507 {
2508 }
2509 }
2511
2513 }
2514 return bRet;
2515}
2516
2518{
2519 tools::Rectangle aNewTextRect = ImpCalculateTextFrame( true/*bHgt*/, true/*bWdt*/ );
2520 bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != getRectangle());
2521 if ( bRet )
2522 {
2523 tools::Rectangle aBoundRect0;
2524 if ( m_pUserCall )
2525 aBoundRect0 = GetCurrentBoundRect();
2526
2527 // taking care of handles that should not been changed
2528 std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles() );
2529
2530 setRectangle(aNewTextRect);
2532
2533 for (const auto& rInteraction : aInteractionHandles)
2534 {
2535 try
2536 {
2537 if ( rInteraction.nMode & CustomShapeHandleModes::RESIZE_FIXED )
2538 rInteraction.xInteraction->setControllerPosition( rInteraction.aPosition );
2539 }
2540 catch ( const uno::RuntimeException& )
2541 {
2542 }
2543 }
2544
2546 SetChanged();
2549 }
2550 return bRet;
2551}
2552void SdrObjCustomShape::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, tools::Rectangle* pViewInit, tools::Rectangle* pViewMin) const
2553{
2554 tools::Rectangle aViewInit;
2555 TakeTextAnchorRect( aViewInit );
2557 {
2558 Point aCenter(aViewInit.Center());
2559 aCenter-=aViewInit.TopLeft();
2560 Point aCenter0(aCenter);
2562 aCenter-=aCenter0;
2563 aViewInit.Move(aCenter.X(),aCenter.Y());
2564 }
2565 Size aAnkSiz(aViewInit.GetSize());
2566 aAnkSiz.AdjustWidth( -1 ); aAnkSiz.AdjustHeight( -1 ); // because GetSize() adds 1
2567 Size aMaxSiz(1000000,1000000);
2568 {
2569 Size aTmpSiz(getSdrModelFromSdrObject().GetMaxObjSize());
2570 if (aTmpSiz.Width()!=0) aMaxSiz.setWidth(aTmpSiz.Width() );
2571 if (aTmpSiz.Height()!=0) aMaxSiz.setHeight(aTmpSiz.Height() );
2572 }
2575
2580 if (nMinWdt<1) nMinWdt=1;
2581 if (nMinHgt<1) nMinHgt=1;
2582 if ( nMaxWdt == 0 || nMaxWdt > aMaxSiz.Width() )
2583 nMaxWdt = aMaxSiz.Width();
2584 if ( nMaxHgt == 0 || nMaxHgt > aMaxSiz.Height() )
2585 nMaxHgt=aMaxSiz.Height();
2586
2588 {
2589 if ( IsVerticalWriting() )
2590 {
2591 nMaxHgt = aAnkSiz.Height();
2592 nMinHgt = nMaxHgt;
2593 }
2594 else
2595 {
2596 nMaxWdt = aAnkSiz.Width();
2597 nMinWdt = nMaxWdt;
2598 }
2599 }
2600 Size aPaperMax(nMaxWdt, nMaxHgt);
2601 Size aPaperMin(nMinWdt, nMinHgt);
2602
2603 if ( pViewMin )
2604 {
2605 *pViewMin = aViewInit;
2606
2607 tools::Long nXFree = aAnkSiz.Width() - aPaperMin.Width();
2608 if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
2609 pViewMin->AdjustRight( -nXFree );
2610 else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
2611 pViewMin->AdjustLeft(nXFree );
2612 else { pViewMin->AdjustLeft(nXFree / 2 ); pViewMin->SetRight( pViewMin->Left() + aPaperMin.Width() ); }
2613
2614 tools::Long nYFree = aAnkSiz.Height() - aPaperMin.Height();
2615 if ( eVAdj == SDRTEXTVERTADJUST_TOP )
2616 pViewMin->AdjustBottom( -nYFree );
2617 else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
2618 pViewMin->AdjustTop(nYFree );
2619 else { pViewMin->AdjustTop(nYFree / 2 ); pViewMin->SetBottom( pViewMin->Top() + aPaperMin.Height() ); }
2620 }
2621
2622 if( IsVerticalWriting() )
2623 aPaperMin.setWidth( 0 );
2624 else
2625 aPaperMin.setHeight( 0 );
2626
2627 if( eHAdj != SDRTEXTHORZADJUST_BLOCK )
2628 aPaperMin.setWidth(0 );
2629
2630 // For complete vertical adjust support, set paper min height to 0, here.
2631 if(SDRTEXTVERTADJUST_BLOCK != eVAdj )
2632 aPaperMin.setHeight( 0 );
2633
2634 if (pPaperMin!=nullptr) *pPaperMin=aPaperMin;
2635 if (pPaperMax!=nullptr) *pPaperMax=aPaperMax;
2636 if (pViewInit!=nullptr) *pViewInit=aViewInit;
2637}
2639{
2640 SdrTextObj::EndTextEdit( rOutl );
2642}
2644{
2645 if ( GetTextBounds( rAnchorRect ) )
2646 {
2647 Point aRotateRef( maSnapRect.Center() );
2648 AdjustRectToTextDistance(rAnchorRect);
2649
2650 if ( rAnchorRect.GetWidth() < 2 )
2651 rAnchorRect.SetRight( rAnchorRect.Left() + 1 ); // minimal width is 2
2652 if ( rAnchorRect.GetHeight() < 2 )
2653 rAnchorRect.SetBottom( rAnchorRect.Top() + 1 ); // minimal height is 2
2655 {
2656 Point aP( rAnchorRect.TopLeft() );
2658 rAnchorRect.SetPos( aP );
2659 }
2660 }
2661 else
2662 SdrTextObj::TakeTextAnchorRect( rAnchorRect );
2663}
2664void SdrObjCustomShape::TakeTextRect( SdrOutliner& rOutliner, tools::Rectangle& rTextRect, bool bNoEditText,
2665 tools::Rectangle* pAnchorRect, bool /*bLineWidth*/) const
2666{
2667 tools::Rectangle aAnkRect; // Rect in which we anchor
2668 TakeTextAnchorRect(aAnkRect);
2671 EEControlBits nStat0=rOutliner.GetControlWord();
2672 Size aNullSize;
2673
2674 rOutliner.SetControlWord(nStat0|EEControlBits::AUTOPAGESIZE);
2675 rOutliner.SetMinAutoPaperSize(aNullSize);
2676 sal_Int32 nMaxAutoPaperWidth = 1000000;
2677 sal_Int32 nMaxAutoPaperHeight= 1000000;
2678
2679 tools::Long nAnkWdt=aAnkRect.GetWidth();
2680 tools::Long nAnkHgt=aAnkRect.GetHeight();
2681
2683 {
2684 if ( IsVerticalWriting() )
2685 nMaxAutoPaperHeight = nAnkHgt;
2686 else
2687 nMaxAutoPaperWidth = nAnkWdt;
2688 }
2690 {
2691 rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
2692 }
2693
2695 {
2696 rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
2697 }
2698 rOutliner.SetMaxAutoPaperSize( Size( nMaxAutoPaperWidth, nMaxAutoPaperHeight ) );
2699 rOutliner.SetPaperSize( aNullSize );
2700
2701 // put text into the Outliner - if necessary the use the text from the EditOutliner
2704 pPara = *GetOutlinerParaObject();
2705 if (mpEditingOutliner && !bNoEditText)
2707
2708 if (pPara)
2709 {
2710 bool bHitTest(&getSdrModelFromSdrObject().GetHitTestOutliner() == &rOutliner);
2711 const SdrTextObj* pTestObj = rOutliner.GetTextObj();
2712
2713 if( !pTestObj || !bHitTest || pTestObj != this ||
2715 {
2716 if( bHitTest )
2717 rOutliner.SetTextObj( this );
2718
2719 rOutliner.SetUpdateLayout(true);
2720 rOutliner.SetText(*pPara);
2721 }
2722 }
2723 else
2724 {
2725 rOutliner.SetTextObj( nullptr );
2726 }
2727
2728 rOutliner.SetUpdateLayout(true);
2729 rOutliner.SetControlWord(nStat0);
2730
2731 SdrText* pText = getActiveText();
2732 if( pText )
2733 pText->CheckPortionInfo( rOutliner );
2734
2735 Point aTextPos(aAnkRect.TopLeft());
2736 Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() has a little added tolerance, no?
2737
2738 // For draw objects containing text correct horizontal/vertical alignment if text is bigger
2739 // than the object itself. Without that correction, the text would always be
2740 // formatted to the left edge (or top edge when vertical) of the draw object.
2741
2742 if( !IsTextFrame() )
2743 {
2744 if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
2745 {
2746 // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
2747 // else the alignment is wanted.
2748 if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
2749 {
2750 SvxAdjust eAdjust = GetObjectItemSet().Get(EE_PARA_JUST).GetAdjust();
2751 switch (eAdjust)
2752 {
2753 case SvxAdjust::Left: eHAdj = SDRTEXTHORZADJUST_LEFT; break;
2754 case SvxAdjust::Right: eHAdj = SDRTEXTHORZADJUST_RIGHT; break;
2755 case SvxAdjust::Center: eHAdj = SDRTEXTHORZADJUST_CENTER; break;
2756 default: break;
2757 }
2758 }
2759 }
2760
2761 if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
2762 {
2763 // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
2764 // else the alignment is wanted.
2765 if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
2766 {
2768 }
2769 }
2770 }
2771
2773 {
2774 tools::Long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
2775 if (eHAdj==SDRTEXTHORZADJUST_CENTER)
2776 aTextPos.AdjustX(nFreeWdt/2 );
2777 if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
2778 aTextPos.AdjustX(nFreeWdt );
2779 }
2781 {
2782 tools::Long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
2783 if (eVAdj==SDRTEXTVERTADJUST_CENTER)
2784 aTextPos.AdjustY(nFreeHgt/2 );
2785 if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
2786 aTextPos.AdjustY(nFreeHgt );
2787 }
2788 if (maGeo.m_nRotationAngle != 0_deg100)
2790
2791 if (pAnchorRect)
2792 *pAnchorRect=aAnkRect;
2793
2794 // using rTextRect together with ContourFrame doesn't always work correctly
2795 rTextRect=tools::Rectangle(aTextPos,aTextSiz);
2796}
2797
2799{
2800 SdrTextObj::NbcSetOutlinerParaObject( std::move(pTextObject) );
2804}
2805
2807{
2808 return new SdrObjCustomShape(rTargetModel, *this);
2809}
2810
2812{
2813 OUString sName(SvxResId(STR_ObjNameSingulCUSTOMSHAPE));
2814 OUString aNm(GetName());
2815 if (!aNm.isEmpty())
2816 sName += " '" + aNm + "'";
2817 return sName;
2818}
2819
2821{
2822 return SvxResId(STR_ObjNamePluralCUSTOMSHAPE);
2823}
2824
2826{
2827 return GetLineGeometry( false );
2828}
2829
2831{
2832 const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
2833 if ( pSdrObject )
2834 return pSdrObject->TakeContour();
2835 return basegfx::B2DPolyPolygon();
2836}
2837
2839{
2840 // #i37011#
2842 SdrObject* pRenderedCustomShape = nullptr;
2843
2844 if ( !mXRenderedCustomShape.is() )
2845 {
2846 // force CustomShape
2848 }
2849
2850 if ( mXRenderedCustomShape.is() )
2851 {
2853 }
2854
2855 if ( pRenderedCustomShape )
2856 {
2857 // Clone to same SdrModel
2858 rtl::Reference<SdrObject> pCandidate(pRenderedCustomShape->CloneSdrObject(pRenderedCustomShape->getSdrModelFromSdrObject()));
2859 DBG_ASSERT(pCandidate, "SdrObjCustomShape::DoConvertToPolyObj: Could not clone SdrObject (!)");
2860 pRetval = pCandidate->DoConvertToPolyObj(bBezier, bAddText);
2861 pCandidate.clear();
2862
2863 if(pRetval)
2864 {
2865 const bool bShadow(GetMergedItem(SDRATTR_SHADOW).GetValue());
2866 if(bShadow)
2867 {
2868 pRetval->SetMergedItem(makeSdrShadowItem(true));
2869 }
2870 }
2871
2872 if(bAddText && HasText() && !IsTextPath())
2873 {
2874 pRetval = ImpConvertAddText(std::move(pRetval), bBezier);
2875 }
2876 }
2877
2878 return pRetval;
2879}
2880
2881void SdrObjCustomShape::InternalSetStyleSheet( SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr, bool bBroadcast )
2882{
2883 // #i40944#
2885 SdrObject::InternalSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr, bBroadcast );
2886}
2887
2889{
2890 // call parent
2891 SdrTextObj::handlePageChange(pOldPage, pNewPage);
2892
2893 if(nullptr != pNewPage)
2894 {
2895 // invalidating rectangles by SetRectsDirty is not sufficient,
2896 // AdjustTextFrameWidthAndHeight() also has to be made, both
2897 // actions are done by NbcSetSnapRect
2898 tools::Rectangle aRectangle(getRectangle()); //creating temporary rectangle #i61108#
2899 NbcSetSnapRect(aRectangle);
2900 }
2901}
2902
2903std::unique_ptr<SdrObjGeoData> SdrObjCustomShape::NewGeoData() const
2904{
2905 return std::make_unique<SdrAShapeObjGeoData>();
2906}
2907
2909{
2911 SdrAShapeObjGeoData& rAGeo=static_cast<SdrAShapeObjGeoData&>(rGeo);
2913 rAGeo.bMirroredX = IsMirroredX();
2914 rAGeo.bMirroredY = IsMirroredY();
2915
2916 const uno::Any* pAny = GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ).GetPropertyValueByName( "AdjustmentValues" );
2917 if ( pAny )
2918 *pAny >>= rAGeo.aAdjustmentSeq;
2919}
2920
2922{
2924 const SdrAShapeObjGeoData& rAGeo=static_cast<const SdrAShapeObjGeoData&>(rGeo);
2926 SetMirroredX( rAGeo.bMirroredX );
2927 SetMirroredY( rAGeo.bMirroredY );
2928
2930 beans::PropertyValue aPropVal;
2931 aPropVal.Name = "AdjustmentValues";
2932 aPropVal.Value <<= rAGeo.aAdjustmentSeq;
2933 rGeometryItem.SetPropertyValue( aPropVal );
2934 SetMergedItem( rGeometryItem );
2935
2937}
2938
2939void SdrObjCustomShape::AdjustToMaxRect(const tools::Rectangle& rMaxRect, bool bShrinkOnly /* = false */)
2940{
2941 SAL_INFO_IF(bShrinkOnly, "svx", "Case bShrinkOnly == true is not implemented yet.");
2942
2943 if (rMaxRect.IsEmpty() || rMaxRect == GetSnapRect())
2944 return;
2945
2946 // Get a matrix, that would produce the existing shape, when applied to a unit square
2947 basegfx::B2DPolyPolygon aPolyPolygon; //not used, but formal needed
2948 basegfx::B2DHomMatrix aMatrix;
2949 TRGetBaseGeometry(aMatrix, aPolyPolygon);
2950 // Using TRSetBaseGeometry(aMatrix, aPolyPolygon) would regenerate the current shape. But
2951 // applying aMatrix to a unit square will not generate the current shape. Scaling,
2952 // rotation and translation are correct, but shear angle has wrong sign. So break up
2953 // matrix and create a mathematically correct new one.
2954 basegfx::B2DTuple aScale;
2955 basegfx::B2DTuple aTranslate;
2956 double fRotate, fShearX;
2957 aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
2958 basegfx::B2DHomMatrix aMathMatrix;
2960 aScale,
2961 basegfx::fTools::equalZero(fShearX) ? 0.0 : -fShearX,
2962 basegfx::fTools::equalZero(fRotate) ? 0.0 : fRotate,
2963 aTranslate);
2964
2965 // Calculate scaling factors from size of the transformed unit polygon as ersatz for the not
2966 // usable current snap rectangle.
2968 aB2DPolygon.transform(aMathMatrix);
2969 basegfx::B2DRange aB2DRange(aB2DPolygon.getB2DRange());
2970 double fPolygonWidth = aB2DRange.getWidth();
2971 if (fPolygonWidth == 0)
2972 fPolygonWidth = 1;
2973 double fPolygonHeight = aB2DRange.getHeight();
2974 if (fPolygonHeight == 0)
2975 fPolygonHeight = 1;
2976 const double aFactorX = static_cast<double>(rMaxRect.GetWidth()) / fPolygonWidth;
2977 const double aFactorY = static_cast<double>(rMaxRect.GetHeight()) / fPolygonHeight;
2978
2979 // Generate matrix, that would produce the desired rMaxRect when applied to unit square
2980 aMathMatrix.scale(aFactorX, aFactorY);
2981 aB2DPolygon = basegfx::utils::createUnitPolygon();
2982 aB2DPolygon.transform(aMathMatrix);
2983 aB2DRange = aB2DPolygon.getB2DRange();
2984 const double fPolygonLeft = aB2DRange.getMinX();
2985 const double fPolygonTop = aB2DRange.getMinY();
2986 aMathMatrix.translate(rMaxRect.Left() - fPolygonLeft, rMaxRect.Top() - fPolygonTop);
2987
2988 // Create a Matrix from aMathMatrix, which is usable with TRSetBaseGeometry
2989 aMathMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
2991 aScale,
2992 basegfx::fTools::equalZero(fShearX) ? 0.0 : -fShearX,
2993 basegfx::fTools::equalZero(fRotate) ? 0.0 : fRotate,
2994 aTranslate);
2995
2996 // Now use TRSetBaseGeometry to actually perform scale, shear, rotate and translate
2997 // on the shape. That considers gluepoints, interaction handles and text area, and includes
2998 // setting rectangles dirty and broadcast.
2999 TRSetBaseGeometry(aMatrix, aPolyPolygon);
3000}
3001
3003{
3004 // The shape might have already flipping in its enhanced geometry. LibreOffice applies
3005 // such after all transformations. We remove it, but remember it to apply them later.
3006 bool bIsMirroredX = IsMirroredX();
3007 bool bIsMirroredY = IsMirroredY();
3008 if (bIsMirroredX || bIsMirroredY)
3009 {
3010 Point aCurrentCenter = GetSnapRect().Center();
3011 if (bIsMirroredX) // mirror on the y-axis
3012 {
3013 Mirror(aCurrentCenter, Point(aCurrentCenter.X(), aCurrentCenter.Y() + 1000));
3014 }
3015 if (bIsMirroredY) // mirror on the x-axis
3016 {
3017 Mirror(aCurrentCenter, Point(aCurrentCenter.X() + 1000, aCurrentCenter.Y()));
3018 }
3019 }
3020
3021 // break up matrix
3022 basegfx::B2DTuple aScale;
3023 basegfx::B2DTuple aTranslate;
3024 double fRotate, fShearX;
3025 rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
3026
3027 // reset object shear and rotations
3028 fObjectRotation = 0.0;
3029 maGeo.m_nRotationAngle = 0_deg100;
3031 maGeo.m_nShearAngle = 0_deg100;
3032 maGeo.RecalcTan();
3033
3034 // if anchor is used, make position relative to it
3035 if(getSdrModelFromSdrObject().IsWriter())
3036 {
3037 if(GetAnchorPos().X() || GetAnchorPos().Y())
3038 {
3039 aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3040 }
3041 }
3042
3043 // scale
3044 Size aSize(FRound(fabs(aScale.getX())), FRound(fabs(aScale.getY())));
3045 // fdo#47434 We need a valid rectangle here
3046 if( !aSize.Height() ) aSize.setHeight( 1 );
3047 if( !aSize.Width() ) aSize.setWidth( 1 );
3048 tools::Rectangle aBaseRect(Point(), aSize);
3049 SetLogicRect(aBaseRect);
3050
3051 // Apply flipping from Matrix, which is a transformation relative to origin
3052 if (basegfx::fTools::less(aScale.getX(), 0.0))
3053 Mirror(Point(0, 0), Point(0, 1000)); // mirror on the y-axis
3054 if (basegfx::fTools::less(aScale.getY(), 0.0))
3055 Mirror(Point(0, 0), Point(1000, 0)); // mirror on the x-axis
3056
3057 // shear?
3058 if(!basegfx::fTools::equalZero(fShearX))
3059 {
3060 GeoStat aGeoStat;
3061 // #i123181# The fix for #121932# here was wrong, the trunk version does not correct the
3062 // mirrored shear values, neither at the object level, nor on the API or XML level. Taking
3063 // back the mirroring of the shear angle
3064 aGeoStat.m_nShearAngle = Degree100(FRound(basegfx::rad2deg<100>(atan(fShearX))));
3065 aGeoStat.RecalcTan();
3066 Shear(Point(), aGeoStat.m_nShearAngle, aGeoStat.mfTanShearAngle, false);
3067 }
3068
3069 // rotation?
3070 if(!basegfx::fTools::equalZero(fRotate))
3071 {
3072 GeoStat aGeoStat;
3073
3074 // #i78696#
3075 // fRotate is mathematically correct, but aGeoStat.nRotationAngle is
3076 // mirrored -> mirror value here
3077 aGeoStat.m_nRotationAngle = NormAngle36000(Degree100(FRound(-basegfx::rad2deg<100>(fRotate))));
3078 aGeoStat.RecalcSinCos();
3079 Rotate(Point(), aGeoStat.m_nRotationAngle, aGeoStat.mfSinRotationAngle, aGeoStat.mfCosRotationAngle);
3080 }
3081
3082 // translate?
3083 if(!aTranslate.equalZero())
3084 {
3085 Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
3086 }
3087
3088 // Apply flipping from enhanced geometry at center of the shape.
3089 if (!(bIsMirroredX || bIsMirroredY))
3090 return;
3091
3092 // create mathematically matrix for the applied transformations
3093 // aScale was in most cases built from a rectangle including edge
3094 // and is therefore mathematically too large by 1
3095 if (aScale.getX() > 2.0 && aScale.getY() > 2.0)
3096 aScale -= basegfx::B2DTuple(1.0, 1.0);
3098 aScale, -fShearX, basegfx::fTools::equalZero(fRotate) ? 0.0 : fRotate,
3099 aTranslate);
3100 // Use matrix to get current center
3101 basegfx::B2DPoint aCenter(0.5,0.5);
3102 aCenter = aMathMat * aCenter;
3103 double fCenterX = aCenter.getX();
3104 double fCenterY = aCenter.getY();
3105 if (bIsMirroredX) // vertical axis
3106 Mirror(Point(FRound(fCenterX),FRound(fCenterY)),
3107 Point(FRound(fCenterX), FRound(fCenterY + 1000.0)));
3108 if (bIsMirroredY) // horizontal axis
3109 Mirror(Point(FRound(fCenterX),FRound(fCenterY)),
3110 Point(FRound(fCenterX + 1000.0), FRound(fCenterY)));
3111}
3112
3113// taking fObjectRotation instead of aGeo.nAngle
3115{
3116 // get turn and shear
3117 double fRotate = basegfx::deg2rad(fObjectRotation);
3118 double fShearX = toRadians(maGeo.m_nShearAngle);
3119
3120 // get aRectangle, this is the unrotated snaprect
3121 tools::Rectangle aRectangle(getRectangle());
3122
3123 bool bMirroredX = IsMirroredX();
3124 bool bMirroredY = IsMirroredY();
3125 if ( bMirroredX || bMirroredY )
3126 { // we have to retrieve the unmirrored rect
3127
3128 GeoStat aNewGeo(maGeo);
3129
3130 if ( bMirroredX )
3131 {
3132 fShearX = -fShearX;
3133 tools::Polygon aPol = Rect2Poly(getRectangle(), aNewGeo);
3134 tools::Rectangle aBoundRect( aPol.GetBoundRect() );
3135
3136 Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
3137 Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
3138 sal_uInt16 i;
3139 sal_uInt16 nPointCount=aPol.GetSize();
3140 for (i=0; i<nPointCount; i++)
3141 {
3142 MirrorPoint(aPol[i],aRef1,aRef2);
3143 }
3144 // mirror polygon and move it a bit
3145 tools::Polygon aPol0(aPol);
3146 aPol[0]=aPol0[1];
3147 aPol[1]=aPol0[0];
3148 aPol[2]=aPol0[3];
3149 aPol[3]=aPol0[2];
3150 aPol[4]=aPol0[1];
3151 aRectangle = svx::polygonToRectangle(aPol, aNewGeo);
3152 }
3153 if ( bMirroredY )
3154 {
3155 fShearX = -fShearX;
3156 tools::Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
3157 tools::Rectangle aBoundRect( aPol.GetBoundRect() );
3158
3159 Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
3160 Point aRef2( aRef1.X() + 1000, aRef1.Y() );
3161 sal_uInt16 i;
3162 sal_uInt16 nPointCount=aPol.GetSize();
3163 for (i=0; i<nPointCount; i++)
3164 {
3165 MirrorPoint(aPol[i],aRef1,aRef2);
3166 }
3167 // mirror polygon and move it a bit
3168 tools::Polygon aPol0(aPol);
3169 aPol[0]=aPol0[1]; // This was WRONG for vertical (!)
3170 aPol[1]=aPol0[0]; // #i121932# Despite my own comment above
3171 aPol[2]=aPol0[3]; // it was *not* wrong even when the reordering
3172 aPol[3]=aPol0[2]; // *seems* to be specific for X-Mirrorings. Oh
3173 aPol[4]=aPol0[1]; // will I be happy when this old stuff is |gone| with aw080 (!)
3174 aRectangle = svx::polygonToRectangle(aPol, aNewGeo);
3175 }
3176 }
3177
3178 // fill other values
3179 basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
3180 basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
3181
3182 // position may be relative to anchorpos, convert
3183 if(getSdrModelFromSdrObject().IsWriter())
3184 {
3185 if(GetAnchorPos().X() || GetAnchorPos().Y())
3186 {
3187 aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
3188 }
3189 }
3190
3191 // build matrix
3193 aScale,
3194 basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
3195 basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
3196 aTranslate);
3197
3198 return false;
3199}
3200
3201std::unique_ptr<sdr::contact::ViewContact> SdrObjCustomShape::CreateObjectSpecificViewContact()
3202{
3203 return std::make_unique<sdr::contact::ViewContactOfSdrObjCustomShape>(*this);
3204}
3205
3206// #i33136#
3207bool SdrObjCustomShape::doConstructOrthogonal(std::u16string_view rName)
3208{
3209 bool bRetval(false);
3210
3211 if(o3tl::equalsIgnoreAsciiCase(rName, u"quadrat"))
3212 {
3213 bRetval = true;
3214 }
3215 else if(o3tl::equalsIgnoreAsciiCase(rName, u"round-quadrat"))
3216 {
3217 bRetval = true;
3218 }
3219 else if(o3tl::equalsIgnoreAsciiCase(rName, u"circle"))
3220 {
3221 bRetval = true;
3222 }
3223 else if(o3tl::equalsIgnoreAsciiCase(rName, u"circle-pie"))
3224 {
3225 bRetval = true;
3226 }
3227 else if(o3tl::equalsIgnoreAsciiCase(rName, u"ring"))
3228 {
3229 bRetval = true;
3230 }
3231
3232 return bRetval;
3233}
3234
3235// #i37011# centralize throw-away of render geometry
3237{
3238 mXRenderedCustomShape = nullptr;
3239 mpLastShadowGeometry = nullptr;
3240}
3241
3242void SdrObjCustomShape::setUnoShape(const uno::Reference<drawing::XShape>& rxUnoShape)
3243{
3244 SdrTextObj::setUnoShape(rxUnoShape);
3245
3246 // The shape engine is created with _current_ shape. This means we
3247 // _must_ reset it when the shape changes.
3248 mxCustomShapeEngine.set(nullptr);
3249}
3250
3252{
3253 OUString sShapeName;
3254 OUString aEngine( GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ).GetValue() );
3255 if ( aEngine.isEmpty()
3256 || aEngine == "com.sun.star.drawing.EnhancedCustomShapeEngine" )
3257 {
3258 OUString sShapeType;
3260 const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "Type" );
3261 if ( pAny && ( *pAny >>= sShapeType ) )
3262 sShapeName = EnhancedCustomShapeTypeNames::GetAccName( sShapeType );
3263 }
3264 return sShapeName;
3265}
3266
3267/* 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
basegfx::BColor getBColor() 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
double mfSinRotationAngle
Definition: svdtrans.hxx:206
void RecalcTan()
Definition: svdtrans.cxx:456
void RecalcSinCos()
Definition: svdtrans.cxx:444
Degree100 m_nShearAngle
Definition: svdtrans.hxx:204
Degree100 m_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()
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
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:913
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:1594
virtual void TakeTextEditArea(Size *pPaperMin, Size *pPaperMax, tools::Rectangle *pViewInit, tools::Rectangle *pViewMin) const override
Definition: svdoashp.cxx:2552
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:2276
void DragMoveCustomShapeHdl(const Point &rDestination, const sal_uInt16 nCustomShapeHdlNum, bool bMoveCalloutRectangle)
Definition: svdoashp.cxx:2044
virtual SdrGluePointList * ForceGluePointList() override
Definition: svdoashp.cxx:1858
basegfx::B2DPolyPolygon GetLineGeometry(const bool bBezierAllowed) const
Definition: svdoashp.cxx:554
static bool doConstructOrthogonal(std::u16string_view rName)
Definition: svdoashp.cxx:3207
virtual void EndTextEdit(SdrOutliner &rOutl) override
Definition: svdoashp.cxx:2638
virtual OUString TakeObjNameSingul() const override
Definition: svdoashp.cxx:2811
virtual void NbcMove(const Size &rSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdoashp.cxx:1497
virtual OUString TakeObjNamePlural() const override
Definition: svdoashp.cxx:2820
const SdrObject * GetSdrObjectShadowFromCustomShape() const
Definition: svdoashp.cxx:422
virtual void InternalSetStyleSheet(SfxStyleSheet *pNewStyleSheet, bool bDontRemoveHardAttr, bool bBroadcast) override
Definition: svdoashp.cxx:2881
virtual bool IsTextPath() const override
Definition: svdoashp.cxx:445
double fObjectRotation
Definition: svdoashp.hxx:78
virtual bool AdjustTextFrameWidthAndHeight() override
Definition: svdoashp.cxx:2517
SVX_DLLPRIVATE void DragCreateObject(SdrDragStat &rDrag)
Definition: svdoashp.cxx:2126
virtual void RestoreGeoData(const SdrObjGeoData &rGeo) override
Definition: svdoashp.cxx:2921
virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat &rDrag) const override
Polygon dragged by the user when creating the object.
Definition: svdoashp.cxx:2191
virtual ~SdrObjCustomShape() override
Definition: svdoashp.cxx:834
virtual void TakeTextRect(SdrOutliner &rOutliner, tools::Rectangle &rTextRect, bool bNoEditText, tools::Rectangle *pAnchorRect, bool bLineWidth=true) const override
Definition: svdoashp.cxx:2664
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdoashp.cxx:3201
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdoashp.cxx:1519
virtual void SetSnapRect(const tools::Rectangle &rRect) override
Definition: svdoashp.cxx:1451
virtual SdrObjKind GetObjIdentifier() const override
Definition: svdoashp.cxx:1388
virtual rtl::Reference< SdrObject > DoConvertToPolyObj(bool bBezier, bool bAddText) const override
Definition: svdoashp.cxx:2838
bool mbAdjustingTextFrameWidthAndHeight
Definition: svdoashp.hxx:79
virtual std::unique_ptr< sdr::properties::BaseProperties > CreateObjectSpecificProperties() override
Definition: svdoashp.cxx:806
virtual rtl::Reference< SdrObject > CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdoashp.cxx:2806
virtual bool IsAutoGrowWidth() const override
Definition: svdoashp.cxx:2207
virtual void AdjustToMaxRect(const tools::Rectangle &rMaxRect, bool bShrinkOnly=false) override
Definition: svdoashp.cxx:2939
OUString GetCustomShapeName() const
Definition: svdoashp.cxx:3251
virtual const SdrGluePointList * GetGluePointList() const override
Definition: svdoashp.cxx:1851
virtual bool NbcAdjustTextFrameWidthAndHeight(bool bHgt=true, bool bWdt=true) override
Definition: svdoashp.cxx:2484
virtual sal_uInt32 GetHdlCount() const override
Via GetHdlCount the number of Handles can be retrieved.
Definition: svdoashp.cxx:1872
virtual bool EndCreate(SdrDragStat &rStat, SdrCreateCmd eCmd) override
Definition: svdoashp.cxx:2181
virtual bool MovCreate(SdrDragStat &rStat) override
Definition: svdoashp.cxx:2169
rtl::Reference< SdrObject > mpLastShadowGeometry
Definition: svdoashp.hxx:96
virtual void NbcSetLogicRect(const tools::Rectangle &rRect) override
Definition: svdoashp.cxx:1461
void ImpCheckCustomGluePointsAreAdded()
Definition: svdoashp.cxx:1750
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdoashp.cxx:2908
virtual void NbcSetOutlinerParaObject(std::optional< OutlinerParaObject > pTextObject) override
Definition: svdoashp.cxx:2798
const SdrObject * GetSdrObjectFromCustomShape() const
Definition: svdoashp.cxx:407
void InvalidateRenderGeometry()
Definition: svdoashp.cxx:3236
void SetMirroredX(const bool bMirroredX)
Definition: svdoashp.cxx:488
virtual void AdaptTextMinSize() override
Definition: svdoashp.cxx:1395
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdoashp.cxx:1330
bool IsMirroredY() const
Definition: svdoashp.cxx:479
virtual bool hasSpecialDrag() const override
The standard transformations (Move,Resize,Rotate,Mirror,Shear) are taken over by the View (TakeXorPol...
Definition: svdoashp.cxx:1903
SVX_DLLPRIVATE void DragResizeCustomShape(const tools::Rectangle &rNewRect)
Definition: svdoashp.cxx:1946
virtual bool TRGetBaseGeometry(basegfx::B2DHomMatrix &rMatrix, basegfx::B2DPolyPolygon &rPolyPolygon) const override
Definition: svdoashp.cxx:3114
virtual void Move(const Size &rSiz) override
Definition: svdoashp.cxx:1484
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:2903
bool UseNoFillStyle() const
Definition: svdoashp.cxx:456
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: svdoashp.cxx:1437
css::uno::Reference< css::drawing::XShape > mXRenderedCustomShape
Definition: svdoashp.hxx:91
virtual void SetVerticalWriting(bool bVertical) override
Definition: svdoashp.cxx:2220
Size m_aSuggestedTextFrameSize
Definition: svdoashp.hxx:129
virtual SdrGluePoint GetVertexGluePoint(sal_uInt16 nNum) const override
Definition: svdoashp.cxx:1718
virtual void handlePageChange(SdrPage *pOldPage, SdrPage *pNewPage) override
Definition: svdoashp.cxx:2888
virtual void SetLogicRect(const tools::Rectangle &rRect) override
Definition: svdoashp.cxx:1474
virtual bool IsAutoGrowHeight() const override
Definition: svdoashp.cxx:2199
bool IsDefaultGeometry(const DefaultType eDefaultType) const
Definition: svdoashp.cxx:1115
tools::Rectangle ImpCalculateTextFrame(const bool bHgt, const bool bWdt)
Definition: svdoashp.cxx:2453
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdoashp.cxx:1688
bool GetTextBounds(tools::Rectangle &rTextBound) const
Definition: svdoashp.cxx:538
virtual basegfx::B2DPolyPolygon TakeXorPoly() const override
The Xor-Polygon is required by the View to drag the object.
Definition: svdoashp.cxx:2825
virtual void TakeTextAnchorRect(tools::Rectangle &rAnchorRect) const override
Definition: svdoashp.cxx:2643
double GetExtraTextRotation(const bool bPreRotation=false) const
Definition: svdoashp.cxx:507
void SetMirroredY(const bool bMirroredY)
Definition: svdoashp.cxx:497
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdoashp.cxx:1638
css::uno::Reference< css::drawing::XCustomShapeEngine > mxCustomShapeEngine
Definition: svdoashp.hxx:93
void MergeDefaultAttributes(const OUString *pType=nullptr)
Definition: svdoashp.cxx:840
virtual basegfx::B2DPolyPolygon TakeContour() const override
contour for TextToContour
Definition: svdoashp.cxx:2830
virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix &rMatrix, const basegfx::B2DPolyPolygon &rPolyPolygon) override
Definition: svdoashp.cxx:3002
bool IsMirroredX() const
Definition: svdoashp.cxx:470
virtual void setUnoShape(const css::uno::Reference< css::drawing::XShape > &rxUnoShape) override
Sets a new UNO representation of the shape.
Definition: svdoashp.cxx:3242
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdoashp.cxx:1878
virtual void Shear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdoashp.cxx:1683
css::uno::Reference< css::drawing::XCustomShapeEngine > const & GetCustomShapeEngine() const
Definition: svdoashp.cxx:372
virtual bool beginSpecialDrag(SdrDragStat &rDrag) const override
Definition: svdoashp.cxx:1908
std::vector< SdrCustomShapeInteraction > GetInteractionHandles() const
Definition: svdoashp.cxx:576
virtual bool applySpecialDrag(SdrDragStat &rDrag) override
Definition: svdoashp.cxx:2085
All geometrical data of an arbitrary object for use in undo/redo.
Definition: svdobj.hxx:174
SdrObject * Next()
Definition: svditer.hxx:63
bool IsMore() const
Definition: svditer.hxx:62
Provides information about various ZObject properties.
Definition: svdobj.hxx:196
Abstract DrawObject.
Definition: svdobj.hxx:260
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
Definition: unoshape.cxx:4020
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:2009
const Point & GetAnchorPos() const
Definition: svdobj.cxx:1653
void ActionChanged() const
Definition: svdobj.cxx:273
virtual SdrGluePointList * ForceGluePointList()
Definition: svdobj.cxx:2319
void moveOutRectangle(sal_Int32 nXDelta, sal_Int32 nYDelta)
Definition: svdobj.cxx:3193
virtual void Shear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear)
Definition: svdobj.cxx:1596
virtual void InternalSetStyleSheet(SfxStyleSheet *pNewStyleSheet, bool bDontRemoveHardAttr, bool bBroadcast)
Definition: svdobj.cxx:2267
std::unique_ptr< SdrObjPlusData > m_pPlusData
Definition: svdobj.hxx:899
virtual void setUnoShape(const css::uno::Reference< css::drawing::XShape > &_rxUnoShape)
Sets a new UNO representation of the shape.
Definition: svdobj.cxx:2824
void BroadcastObjectChange() const
Definition: svdobj.cxx:1018
void SetObjectItemSet(const SfxItemSet &rSet)
Definition: svdobj.cxx:1994
bool LineIsOutsideGeometry() const
Definition: svdobj.hxx:852
const SfxPoolItem & GetObjectItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:2004
virtual void Mirror(const Point &rRef1, const Point &rRef2)
Definition: svdobj.cxx:1587
bool m_bSnapRectDirty
Definition: svdobj.hxx:902
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:962
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:289
SdrObjUserCall * m_pUserCall
Definition: svdobj.hxx:897
virtual const OUString & GetName() const
Definition: svdobj.cxx:771
virtual void Rotate(const Point &rRef, Degree100 nAngle, double sn, double cs)
Definition: svdobj.cxx:1576
void SendUserCall(SdrUserCallType eUserCall, const tools::Rectangle &rBoundRect) const
Definition: svdobj.cxx:2763
virtual void SetChanged()
Definition: svdobj.cxx:1042
virtual const tools::Rectangle & GetLastBoundRect() const
Definition: svdobj.cxx:977
virtual rtl::Reference< SdrObject > CloneSdrObject(SdrModel &rTargetModel) const =0
virtual const SdrGluePointList * GetGluePointList() const
Definition: svdobj.cxx:2312
virtual basegfx::B2DPolyPolygon TakeContour() const
contour for TextToContour
Definition: svdobj.cxx:1140
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1974
void SetMergedItem(const SfxPoolItem &rItem)
Definition: svdobj.cxx:1984
bool m_bClosedObj
Definition: svdobj.hxx:915
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:1439
virtual void SetBoundAndSnapRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:509
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1969
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const
Definition: svdobj.cxx:631
void SetTextObj(const SdrTextObj *pObj)
Definition: svdoutl.cxx:43
const SdrTextObj * GetTextObj() const
Definition: svdoutl.cxx:91
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:379
SdrTextHorzAdjust GetTextHorizontalAdjust() const
Definition: svdotext.cxx:346
GeoStat maGeo
Definition: svdotext.hxx:196
tools::Long GetMaxTextFrameHeight() const
Definition: svdotext.cxx:1786
virtual void SaveGeoData(SdrObjGeoData &rGeo) const override
Definition: svdotext.cxx:1499
tools::Rectangle const & getRectangle() const
Definition: svdotext.hxx:170
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdotxtr.cxx:238
friend class SdrObjCustomShape
Definition: svdotext.hxx:161
virtual void RestoreGeoData(const SdrObjGeoData &rGeo) override
Definition: svdotext.cxx:1507
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdotxtr.cxx:214
virtual void NbcMove(const Size &rSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdotxtr.cxx:95
tools::Long GetTextLowerDistance() const
Bottom inner spacing to borders.
Definition: svdotext.cxx:1834
SdrOutliner & ImpGetDrawOutliner() const
Definition: svdotext.cxx:1194
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:1781
void moveRectangle(sal_Int32 nXDelta, sal_Int32 nYDelta)
Definition: svdotext.hxx:185
virtual SdrText * getActiveText() const
returns the currently active text.
Definition: svdotext.cxx:2147
SdrOutliner * mpEditingOutliner
Definition: svdotext.hxx:207
tools::Long GetMaxTextFrameWidth() const
Definition: svdotext.cxx:1796
virtual void TakeTextAnchorRect(::tools::Rectangle &rAnchorRect) const
Definition: svdotext.cxx:656
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotext.cxx:1412
void ImpCheckShear()
Definition: svdotext.cxx:420
tools::Long GetTextLeftDistance() const
Left inner spacing to borders
Definition: svdotext.cxx:1819
tools::Long GetTextRightDistance() const
Right inner spacing to borders
Definition: svdotext.cxx:1824
virtual const tools::Rectangle & GetLogicRect() const override
Definition: svdotxtr.cxx:70
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:411
tools::Rectangle ImpDragCalcRect(const SdrDragStat &rDrag) const
Definition: svdotxdr.cxx:75
virtual bool HasText() const override
Definition: svdotxat.cxx:420
virtual void handlePageChange(SdrPage *pOldPage, SdrPage *pNewPage) override
Definition: svdotext.cxx:480
virtual void NbcSetOutlinerParaObject(std::optional< OutlinerParaObject > pTextObject) override
Definition: svdotext.cxx:1421
tools::Long GetMinTextFrameWidth() const
Definition: svdotext.cxx:1791
virtual void AddToHdlList(SdrHdlList &rHdlList) const override
Definition: svdotxdr.cxx:41
bool IsTextFrame() const
Definition: svdotext.hxx:359
SdrTextVertAdjust GetTextVerticalAdjust() const
Definition: svdotext.cxx:378
void AdjustRectToTextDistance(tools::Rectangle &rAnchorRect) const
Definition: svdotext.cxx:623
const GeoStat & GetGeoStat() const
Definition: svdotext.hxx:419
void ForceOutlinerParaObject()
Definition: svdotext.cxx:1531
rtl::Reference< SdrObject > ImpConvertAddText(rtl::Reference< SdrObject > pObj, bool bBezier) const
Definition: svdotxtr.cxx:459
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdotxtr.cxx:103
virtual void EndTextEdit(SdrOutliner &rOutl)
Definition: svdotxed.cxx:264
void setRectangle(tools::Rectangle const &rRectangle)
Definition: svdotext.hxx:175
bool mbTextFrame
Definition: svdotext.hxx:242
tools::Long GetTextUpperDistance() const
Top inner spacing to borders.
Definition: svdotext.cxx:1829
virtual bool IsVerticalWriting() const
Definition: svdotext.cxx:1552
virtual void NbcRotate(const Point &rRef, Degree100 nAngle, double sn, double cs) override
Definition: svdotxtr.cxx:190
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
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
sal_uInt16 GetStartIntens() const
void SetColorStops(const basegfx::BColorStops &rSteps)
const basegfx::BColorStops & GetColorStops() const
sal_uInt16 GetEndIntens() 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)
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 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)
tools::Rectangle polygonToRectangle(const tools::Polygon &rPolygon, GeoStat &rGeo)
Definition: svdtrans.cxx:482
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:30
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:672
#define DEFAULT_MINIMUM_SIGNED_COMPARE
Definition: svdoashp.cxx:671
static sal_Int32 GetNumberOfProperties(const SvxMSDffHandle *pData)
Definition: svdoashp.cxx:674
static MSO_SPT ImpGetCustomShapeType(const SdrObjCustomShape &rCustoShape)
Definition: svdoashp.cxx:171
static void lcl_ShapePropertiesFromDFF(const SvxMSDffHandle *pData, beans::PropertyValues &rPropValues)
Definition: svdoashp.cxx:711
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 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
Center
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:4013
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)