1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <tools/bigint.hxx>
21 #include <tools/helpers.hxx>
22 #include <svx/xlnwtit.hxx>
23 #include <svl/style.hxx>
24 #include <svx/svdocapt.hxx>
25 #include <svx/xpool.hxx>
26 #include <svx/xpoly.hxx>
27 #include <svx/svdattrx.hxx>
28 #include <svx/svdpool.hxx>
29 #include <svx/svdetc.hxx>
30 #include <svx/svdtrans.hxx>
31 #include <svx/svdhdl.hxx>
32 #include <svx/svddrag.hxx>
33 #include <svx/svdmodel.hxx>
34 #include <svx/svdview.hxx> // for RectSnap
35 #include "svx/svdglob.hxx" // StringCache
36 #include "svx/svdstr.hrc" // the object's name
37 #include <svx/svdogrp.hxx>
38 #include <svx/svdpage.hxx>
39 #include <svx/xflhtit.hxx>
40 #include <svx/xflclit.hxx>
41 #include <svx/xfltrit.hxx>
42 #include <editeng/eeitem.hxx>
43 #include <svx/sdr/properties/captionproperties.hxx>
44 #include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx>
45 #include <basegfx/tuple/b2dtuple.hxx>
46 #include <basegfx/matrix/b2dhommatrix.hxx>
47 #include <basegfx/polygon/b2dpolygon.hxx>
48 #include <basegfx/range/b2drange.hxx>
49 #include <basegfx/polygon/b2dpolygontools.hxx>
50 #include <svx/sdrhittesthelper.hxx>
51 #include "svdconv.hxx"
53 ////////////////////////////////////////////////////////////////////////////////////////////////////
55 enum EscDir
{LKS
,RTS
,OBN
,UNT
};
66 SdrCaptionEscDir eEscDir
;
75 bFixedAngle
=sal_False
;
78 eEscDir
=SDRCAPT_ESCHORIZONTAL
;
85 void CalcEscPos(const Point
& rTail
, const Rectangle
& rRect
, Point
& rPt
, EscDir
& rDir
) const;
88 void ImpCaptParams::CalcEscPos(const Point
& rTailPt
, const Rectangle
& rRect
, Point
& rPt
, EscDir
& rDir
) const
90 Point
aTl(rTailPt
); // copy locally for performance reasons
93 nX
=rRect
.Right()-rRect
.Left();
94 nX
=BigMulDiv(nX
,nEscRel
,10000);
95 nY
=rRect
.Bottom()-rRect
.Top();
96 nY
=BigMulDiv(nY
,nEscRel
,10000);
105 bool bTryH
=eEscDir
==SDRCAPT_ESCBESTFIT
;
107 if (eType
!=SDRCAPT_TYPE1
) {
108 bTryH
=eEscDir
==SDRCAPT_ESCHORIZONTAL
;
110 bTryH
=eEscDir
==SDRCAPT_ESCVERTICAL
;
113 bool bTryV
=eEscDir
==SDRCAPT_ESCBESTFIT
;
115 if (eType
!=SDRCAPT_TYPE1
) {
116 bTryV
=eEscDir
==SDRCAPT_ESCVERTICAL
;
118 bTryV
=eEscDir
==SDRCAPT_ESCHORIZONTAL
;
123 Point
aLft(rRect
.Left()-nGap
,nY
);
124 Point
aRgt(rRect
.Right()+nGap
,nY
);
125 bool bLft
=(aTl
.X()-aLft
.X()<aRgt
.X()-aTl
.X());
135 Point
aTop(nX
,rRect
.Top()-nGap
);
136 Point
aBtm(nX
,rRect
.Bottom()+nGap
);
137 bool bTop
=(aTl
.Y()-aTop
.Y()<aBtm
.Y()-aTl
.Y());
147 bool bTakeIt
=eEscDir
!=SDRCAPT_ESCBESTFIT
;
149 BigInt
aHorX(aBestPt
.X()-aTl
.X()); aHorX
*=aHorX
;
150 BigInt
aHorY(aBestPt
.Y()-aTl
.Y()); aHorY
*=aHorY
;
151 BigInt
aVerX(aBest2
.X()-aTl
.X()); aVerX
*=aVerX
;
152 BigInt
aVerY(aBest2
.Y()-aTl
.Y()); aVerY
*=aVerY
;
153 if (eType
!=SDRCAPT_TYPE1
) {
154 bTakeIt
=aVerX
+aVerY
<aHorX
+aHorY
;
156 bTakeIt
=aVerX
+aVerY
>=aHorX
+aHorY
;
168 //////////////////////////////////////////////////////////////////////////////
169 // BaseProperties section
171 sdr::properties::BaseProperties
* SdrCaptionObj::CreateObjectSpecificProperties()
173 return new sdr::properties::CaptionProperties(*this);
176 //////////////////////////////////////////////////////////////////////////////
177 // DrawContact section
179 sdr::contact::ViewContact
* SdrCaptionObj::CreateObjectSpecificViewContact()
181 return new sdr::contact::ViewContactOfSdrCaptionObj(*this);
184 //////////////////////////////////////////////////////////////////////////////
186 TYPEINIT1(SdrCaptionObj
,SdrRectObj
);
188 SdrCaptionObj::SdrCaptionObj():
189 SdrRectObj(OBJ_TEXT
),
190 aTailPoly(3), // default size: 3 points = 2 lines
191 mbSpecialTextBoxShadow(sal_False
),
192 mbFixedTail(sal_False
)
196 SdrCaptionObj::SdrCaptionObj(const Rectangle
& rRect
, const Point
& rTail
):
197 SdrRectObj(OBJ_TEXT
,rRect
),
198 aTailPoly(3), // default size: 3 points = 2 lines
199 mbSpecialTextBoxShadow(sal_False
),
200 mbFixedTail(sal_False
)
202 aTailPoly
[0]=maFixedTailPos
=rTail
;
205 SdrCaptionObj::~SdrCaptionObj()
209 void SdrCaptionObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
211 rInfo
.bRotateFreeAllowed
=sal_False
;
212 rInfo
.bRotate90Allowed
=sal_False
;
213 rInfo
.bMirrorFreeAllowed
=sal_False
;
214 rInfo
.bMirror45Allowed
=sal_False
;
215 rInfo
.bMirror90Allowed
=sal_False
;
216 rInfo
.bTransparenceAllowed
= sal_False
;
217 rInfo
.bGradientAllowed
= sal_False
;
218 rInfo
.bShearAllowed
=sal_False
;
219 rInfo
.bEdgeRadiusAllowed
=sal_False
;
220 rInfo
.bCanConvToPath
=sal_True
;
221 rInfo
.bCanConvToPoly
=sal_True
;
222 rInfo
.bCanConvToPathLineToArea
=sal_False
;
223 rInfo
.bCanConvToPolyLineToArea
=sal_False
;
224 rInfo
.bCanConvToContour
= (rInfo
.bCanConvToPoly
|| LineGeometryUsageIsNecessary());
227 sal_uInt16
SdrCaptionObj::GetObjIdentifier() const
229 return sal_uInt16(OBJ_CAPTION
);
232 SdrCaptionObj
* SdrCaptionObj::Clone() const
234 return CloneHelper
< SdrCaptionObj
>();
237 void SdrCaptionObj::TakeObjNameSingul(XubString
& rName
) const
239 rName
=ImpGetResStr(STR_ObjNameSingulCAPTION
);
241 String
aName( GetName() );
244 rName
+= sal_Unicode(' ');
245 rName
+= sal_Unicode('\'');
247 rName
+= sal_Unicode('\'');
251 void SdrCaptionObj::TakeObjNamePlural(XubString
& rName
) const
253 rName
=ImpGetResStr(STR_ObjNamePluralCAPTION
);
256 basegfx::B2DPolyPolygon
SdrCaptionObj::TakeXorPoly() const
258 basegfx::B2DPolyPolygon
aPolyPoly(SdrRectObj::TakeXorPoly());
259 aPolyPoly
.append(aTailPoly
.getB2DPolygon());
264 sal_uInt32
SdrCaptionObj::GetHdlCount() const
266 sal_uInt32
nAnz1(SdrRectObj::GetHdlCount());
267 // Currently only dragging the tail's end is implemented.
271 SdrHdl
* SdrCaptionObj::GetHdl(sal_uInt32 nHdlNum
) const
273 const sal_uInt32
nRectHdlAnz(SdrRectObj::GetHdlCount());
275 if(nHdlNum
< nRectHdlAnz
)
277 return SdrRectObj::GetHdl(nHdlNum
);
281 sal_uInt32
nPntNum(nHdlNum
);
282 nPntNum
-= nRectHdlAnz
;
284 if(nPntNum
< aTailPoly
.GetSize())
286 SdrHdl
* pHdl
= new SdrHdl(aTailPoly
.GetPoint((sal_uInt16
)nPntNum
), HDL_POLY
);
287 pHdl
->SetPolyNum(1L);
288 pHdl
->SetPointNum(nPntNum
);
298 ////////////////////////////////////////////////////////////////////////////////////////////////////
300 bool SdrCaptionObj::hasSpecialDrag() const
305 bool SdrCaptionObj::beginSpecialDrag(SdrDragStat
& rDrag
) const
307 const SdrHdl
* pHdl
= rDrag
.GetHdl();
308 rDrag
.SetEndDragChangesAttributes(true);
309 rDrag
.SetEndDragChangesGeoAndAttributes(true);
311 if(pHdl
&& 0 == pHdl
->GetPolyNum())
313 return SdrRectObj::beginSpecialDrag(rDrag
);
317 rDrag
.SetOrtho8Possible(true);
324 rDrag
.SetNoSnap(true);
325 rDrag
.SetActionRect(aRect
);
327 Point
aHit(rDrag
.GetStart());
329 if(rDrag
.GetPageView() && SdrObjectPrimitiveHit(*this, aHit
, 0, *rDrag
.GetPageView(), 0, false))
336 if((1 == pHdl
->GetPolyNum()) && (0 == pHdl
->GetPointNum()))
344 bool SdrCaptionObj::applySpecialDrag(SdrDragStat
& rDrag
)
346 const SdrHdl
* pHdl
= rDrag
.GetHdl();
348 if(pHdl
&& 0 == pHdl
->GetPolyNum())
350 const bool bRet(SdrRectObj::applySpecialDrag(rDrag
));
358 Point
aDelt(rDrag
.GetNow()-rDrag
.GetStart());
362 aRect
.Move(aDelt
.X(),aDelt
.Y());
366 aTailPoly
[0] += aDelt
;
376 String
SdrCaptionObj::getSpecialDragComment(const SdrDragStat
& rDrag
) const
378 const bool bCreateComment(rDrag
.GetView() && this == rDrag
.GetView()->GetCreateObj());
386 const SdrHdl
* pHdl
= rDrag
.GetHdl();
388 if(pHdl
&& 0 == pHdl
->GetPolyNum())
390 return SdrRectObj::getSpecialDragComment(rDrag
);
398 ImpTakeDescriptionStr(STR_DragCaptFram
, aStr
);
402 ImpTakeDescriptionStr(STR_DragCaptTail
, aStr
);
410 ////////////////////////////////////////////////////////////////////////////////////////////////////
412 void SdrCaptionObj::ImpGetCaptParams(ImpCaptParams
& rPara
) const
414 const SfxItemSet
& rSet
= GetObjectItemSet();
415 rPara
.eType
=((SdrCaptionTypeItem
&) (rSet
.Get(SDRATTR_CAPTIONTYPE
))).GetValue();
416 rPara
.bFixedAngle
=((SdrCaptionFixedAngleItem
&)(rSet
.Get(SDRATTR_CAPTIONANGLE
))).GetValue();
417 rPara
.nAngle
=((SdrCaptionAngleItem
&) (rSet
.Get(SDRATTR_CAPTIONFIXEDANGLE
))).GetValue();
418 rPara
.nGap
=((SdrCaptionGapItem
&) (rSet
.Get(SDRATTR_CAPTIONGAP
))).GetValue();
419 rPara
.eEscDir
=((SdrCaptionEscDirItem
&) (rSet
.Get(SDRATTR_CAPTIONESCDIR
))).GetValue();
420 rPara
.bEscRel
=((SdrCaptionEscIsRelItem
&) (rSet
.Get(SDRATTR_CAPTIONESCISREL
))).GetValue();
421 rPara
.nEscRel
=((SdrCaptionEscRelItem
&) (rSet
.Get(SDRATTR_CAPTIONESCREL
))).GetValue();
422 rPara
.nEscAbs
=((SdrCaptionEscAbsItem
&) (rSet
.Get(SDRATTR_CAPTIONESCABS
))).GetValue();
423 rPara
.nLineLen
=((SdrCaptionLineLenItem
&) (rSet
.Get(SDRATTR_CAPTIONLINELEN
))).GetValue();
424 rPara
.bFitLineLen
=((SdrCaptionFitLineLenItem
&)(rSet
.Get(SDRATTR_CAPTIONFITLINELEN
))).GetValue();
427 void SdrCaptionObj::ImpRecalcTail()
430 ImpGetCaptParams(aPara
);
431 ImpCalcTail(aPara
,aTailPoly
,aRect
);
437 // SdrCaptionObj::ImpCalcTail1 does move the object(!). What a hack.
438 // I really wonder why this had not triggered problems before. I am
439 // sure there are some places where SetTailPos() is called at least
440 // twice or SetSnapRect after it again just to work around this.
441 // Changed this method to not do that.
442 // Also found why this has been done: For interactive dragging of the
443 // tail end pos for SDRCAPT_TYPE1. This sure was the simplest method
444 // to achieve this, at the cost of making a whole group of const methods
445 // of this object implicitly change the object's position.
446 void SdrCaptionObj::ImpCalcTail1(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
457 rPara
.CalcEscPos(aTl
, rRect
, aEscPos
, eEscDir
);
460 if(eEscDir
==LKS
|| eEscDir
==RTS
)
462 aPol
[0].X() = aEscPos
.X();
466 aPol
[0].Y() = aEscPos
.Y();
472 void SdrCaptionObj::ImpCalcTail2(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
473 { // Gap/EscDir/EscPos/Angle
480 rPara
.CalcEscPos(aTl
,rRect
,aEscPos
,eEscDir
);
483 if (!rPara
.bFixedAngle
) {
484 // TODO: Implementation missing.
489 void SdrCaptionObj::ImpCalcTail3(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
490 { // Gap/EscDir/EscPos/Angle/LineLen
497 rPara
.CalcEscPos(aTl
,rRect
,aEscPos
,eEscDir
);
501 if (eEscDir
==LKS
|| eEscDir
==RTS
) {
502 if (rPara
.bFitLineLen
) {
503 aPol
[1].X()=(aTl
.X()+aEscPos
.X())/2;
505 if (eEscDir
==LKS
) aPol
[1].X()-=rPara
.nLineLen
;
506 else aPol
[1].X()+=rPara
.nLineLen
;
509 if (rPara
.bFitLineLen
) {
510 aPol
[1].Y()=(aTl
.Y()+aEscPos
.Y())/2;
512 if (eEscDir
==OBN
) aPol
[1].Y()-=rPara
.nLineLen
;
513 else aPol
[1].Y()+=rPara
.nLineLen
;
516 if (!rPara
.bFixedAngle
) {
517 // TODO: Implementation missing.
522 void SdrCaptionObj::ImpCalcTail4(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
524 ImpCalcTail3(rPara
,rPoly
,rRect
);
527 void SdrCaptionObj::ImpCalcTail(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
529 switch (rPara
.eType
) {
530 case SDRCAPT_TYPE1
: ImpCalcTail1(rPara
,rPoly
,rRect
); break;
531 case SDRCAPT_TYPE2
: ImpCalcTail2(rPara
,rPoly
,rRect
); break;
532 case SDRCAPT_TYPE3
: ImpCalcTail3(rPara
,rPoly
,rRect
); break;
533 case SDRCAPT_TYPE4
: ImpCalcTail4(rPara
,rPoly
,rRect
); break;
537 bool SdrCaptionObj::BegCreate(SdrDragStat
& rStat
)
539 if (aRect
.IsEmpty()) return sal_False
; // Create currently only works with the given Rect
542 ImpGetCaptParams(aPara
);
543 aRect
.SetPos(rStat
.GetNow());
544 aTailPoly
[0]=rStat
.GetStart();
545 ImpCalcTail(aPara
,aTailPoly
,aRect
);
546 rStat
.SetActionRect(aRect
);
550 bool SdrCaptionObj::MovCreate(SdrDragStat
& rStat
)
553 ImpGetCaptParams(aPara
);
554 aRect
.SetPos(rStat
.GetNow());
555 ImpCalcTail(aPara
,aTailPoly
,aRect
);
556 rStat
.SetActionRect(aRect
);
558 bSnapRectDirty
=sal_True
;
562 bool SdrCaptionObj::EndCreate(SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
565 ImpGetCaptParams(aPara
);
566 aRect
.SetPos(rStat
.GetNow());
567 ImpCalcTail(aPara
,aTailPoly
,aRect
);
569 return (eCmd
==SDRCREATE_FORCEEND
|| rStat
.GetPointAnz()>=2);
572 bool SdrCaptionObj::BckCreate(SdrDragStat
& /*rStat*/)
577 void SdrCaptionObj::BrkCreate(SdrDragStat
& /*rStat*/)
581 basegfx::B2DPolyPolygon
SdrCaptionObj::TakeCreatePoly(const SdrDragStat
& /*rDrag*/) const
583 basegfx::B2DPolyPolygon aRetval
;
584 const basegfx::B2DRange
aRange(aRect
.Left(), aRect
.Top(), aRect
.Right(), aRect
.Bottom());
585 aRetval
.append(basegfx::tools::createPolygonFromRect(aRange
));
586 aRetval
.append(aTailPoly
.getB2DPolygon());
590 Pointer
SdrCaptionObj::GetCreatePointer() const
592 return Pointer(POINTER_DRAW_CAPTION
);
595 void SdrCaptionObj::NbcMove(const Size
& rSiz
)
597 SdrRectObj::NbcMove(rSiz
);
598 MovePoly(aTailPoly
,rSiz
);
600 SetTailPos(GetFixedTailPos());
603 void SdrCaptionObj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
605 SdrRectObj::NbcResize(rRef
,xFact
,yFact
);
606 ResizePoly(aTailPoly
,rRef
,xFact
,yFact
);
609 SetTailPos(GetFixedTailPos());
612 void SdrCaptionObj::NbcSetRelativePos(const Point
& rPnt
)
614 Point
aRelPos0(aTailPoly
.GetPoint(0)-aAnchor
);
615 Size
aSiz(rPnt
.X()-aRelPos0
.X(),rPnt
.Y()-aRelPos0
.Y());
616 NbcMove(aSiz
); // This also calls SetRectsDirty()
619 Point
SdrCaptionObj::GetRelativePos() const
621 return aTailPoly
.GetPoint(0)-aAnchor
;
624 void SdrCaptionObj::NbcSetAnchorPos(const Point
& rPnt
)
626 SdrRectObj::NbcSetAnchorPos(rPnt
);
627 // TODO: Implementation missing.
630 const Point
& SdrCaptionObj::GetAnchorPos() const
632 // TODO: Implementation missing.
633 return SdrRectObj::GetAnchorPos();
636 void SdrCaptionObj::RecalcSnapRect()
638 SdrRectObj::RecalcSnapRect();
640 // TODO: Implementation missing.
643 const Rectangle
& SdrCaptionObj::GetSnapRect() const
645 return SdrRectObj::GetSnapRect();
648 void SdrCaptionObj::NbcSetSnapRect(const Rectangle
& rRect
)
651 // Move back to see the rectangle of the underlying SdrRectObj
652 // as the SnapRect, without the TailPos. That simplifies SnapRect
653 // handling again, if not allows it at all...
654 SdrRectObj::NbcSetSnapRect(rRect
);
657 const Rectangle
& SdrCaptionObj::GetLogicRect() const
662 void SdrCaptionObj::NbcSetLogicRect(const Rectangle
& rRect
)
664 SdrRectObj::NbcSetLogicRect(rRect
);
668 const Point
& SdrCaptionObj::GetTailPos() const
673 void SdrCaptionObj::SetTailPos(const Point
& rPos
)
675 if (aTailPoly
.GetSize()==0 || aTailPoly
[0]!=rPos
) {
676 Rectangle aBoundRect0
; if (pUserCall
!=NULL
) aBoundRect0
=GetLastBoundRect();
679 BroadcastObjectChange();
680 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
684 void SdrCaptionObj::NbcSetTailPos(const Point
& rPos
)
690 sal_uInt32
SdrCaptionObj::GetSnapPointCount() const
692 // TODO: Implementation missing.
696 Point
SdrCaptionObj::GetSnapPoint(sal_uInt32
/*i*/) const
698 // TODO: Implementation missing.
702 void SdrCaptionObj::SetModel(SdrModel
* pNewModel
)
704 SdrRectObj::SetModel(pNewModel
);
708 void SdrCaptionObj::Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
710 SdrRectObj::Notify(rBC
,rHint
);
714 SdrObjGeoData
* SdrCaptionObj::NewGeoData() const
716 return new SdrCaptObjGeoData
;
719 void SdrCaptionObj::SaveGeoData(SdrObjGeoData
& rGeo
) const
721 SdrRectObj::SaveGeoData(rGeo
);
722 SdrCaptObjGeoData
& rCGeo
=(SdrCaptObjGeoData
&)rGeo
;
723 rCGeo
.aTailPoly
=aTailPoly
;
726 void SdrCaptionObj::RestGeoData(const SdrObjGeoData
& rGeo
)
728 SdrRectObj::RestGeoData(rGeo
);
729 SdrCaptObjGeoData
& rCGeo
=(SdrCaptObjGeoData
&)rGeo
;
730 aTailPoly
=rCGeo
.aTailPoly
;
733 SdrObject
* SdrCaptionObj::DoConvertToPolyObj(sal_Bool bBezier
, bool bAddText
) const
735 SdrObject
* pRect
=SdrRectObj::DoConvertToPolyObj(bBezier
, bAddText
);
736 SdrObject
* pTail
= ImpConvertMakeObj(basegfx::B2DPolyPolygon(aTailPoly
.getB2DPolygon()), sal_False
, bBezier
);
737 SdrObject
* pRet
=(pTail
!=NULL
) ? pTail
: pRect
;
738 if (pTail
!=NULL
&& pRect
!=NULL
) {
739 bool bInsRect
= true;
740 bool bInsTail
= true;
741 SdrObjList
* pOL
=pTail
->GetSubList();
742 if (pOL
!=NULL
) { pRet
=pRect
; bInsTail
= false; }
743 if (pOL
==NULL
) pOL
=pRect
->GetSubList();
744 if (pOL
!=NULL
) { pRet
=pRect
; bInsRect
= false; }
746 SdrObjGroup
* pGrp
=new SdrObjGroup
;
747 pOL
=pGrp
->GetSubList();
750 if (bInsRect
) pOL
->NbcInsertObject(pRect
);
751 if (bInsTail
) pOL
->NbcInsertObject(pTail
,0);
757 // Add own implementation for TRSetBaseGeometry to handle TailPos over changes.
758 void SdrCaptionObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix
& rMatrix
, const basegfx::B2DPolyPolygon
& /*rPolyPolygon*/)
761 basegfx::B2DTuple aScale
;
762 basegfx::B2DTuple aTranslate
;
763 double fRotate
, fShearX
;
764 rMatrix
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
766 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
767 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
768 if(basegfx::fTools::less(aScale
.getX(), 0.0) && basegfx::fTools::less(aScale
.getY(), 0.0))
770 aScale
.setX(fabs(aScale
.getX()));
771 aScale
.setY(fabs(aScale
.getY()));
772 fRotate
= fmod(fRotate
+ F_PI
, F_2PI
);
775 // force metric to pool metric
776 SfxMapUnit eMapUnit
= pModel
->GetItemPool().GetMetric(0);
777 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
781 case SFX_MAPUNIT_TWIP
:
784 aTranslate
.setX(ImplMMToTwips(aTranslate
.getX()));
785 aTranslate
.setY(ImplMMToTwips(aTranslate
.getY()));
788 aScale
.setX(ImplMMToTwips(aScale
.getX()));
789 aScale
.setY(ImplMMToTwips(aScale
.getY()));
795 OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
800 // if anchor is used, make position relative to it
801 if( pModel
->IsWriter() )
803 if(GetAnchorPos().X() || GetAnchorPos().Y())
805 aTranslate
+= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
810 Point
aPoint(FRound(aTranslate
.getX()), FRound(aTranslate
.getY()));
811 Rectangle
aBaseRect(aPoint
, Size(FRound(aScale
.getX()), FRound(aScale
.getY())));
813 // set BaseRect, but rescue TailPos over this call
814 const Point aTailPoint
= GetTailPos();
815 SetSnapRect(aBaseRect
);
816 SetTailPos(aTailPoint
);
821 basegfx::B2DPolygon
SdrCaptionObj::getTailPolygon() const
823 return aTailPoly
.getB2DPolygon();
826 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */