1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdocapt.cxx,v $
10 * $Revision: 1.30.18.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <tools/bigint.hxx>
34 #include <svx/xlnwtit.hxx>
35 #include <svtools/style.hxx>
36 #include <svx/svdocapt.hxx>
37 #include <svx/xpool.hxx>
38 #include <svx/xpoly.hxx>
39 #include <svx/svdattrx.hxx>
40 #include <svx/svdpool.hxx>
41 #include <svx/svdetc.hxx>
42 #include <svx/svdtrans.hxx>
43 #include <svx/svdhdl.hxx>
44 #include <svx/svddrag.hxx>
45 #include <svx/svdmodel.hxx>
46 #include <svx/svdview.hxx> // fuer RectSnap
47 #include "svdglob.hxx" // StringCache
48 #include "svdstr.hrc" // Objektname
49 #include <svx/svdogrp.hxx>
50 #include <svx/svdpage.hxx>
51 #include <svx/xflhtit.hxx>
52 #include <svx/xflclit.hxx>
53 #include <svx/xfltrit.hxx>
54 #include <svx/eeitem.hxx>
55 #include <svx/sdr/properties/captionproperties.hxx>
56 #include <vcl/salbtype.hxx> // FRound
57 #include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx>
58 #include <basegfx/tuple/b2dtuple.hxx>
59 #include <basegfx/matrix/b2dhommatrix.hxx>
60 #include <basegfx/polygon/b2dpolygon.hxx>
61 #include <basegfx/range/b2drange.hxx>
62 #include <basegfx/polygon/b2dpolygontools.hxx>
63 #include <svx/sdrhittesthelper.hxx>
66 inline double ImplTwipsToMM(double fVal
) { return (fVal
* (127.0 / 72.0)); }
67 inline double ImplMMToTwips(double fVal
) { return (fVal
* (72.0 / 127.0)); }
69 ////////////////////////////////////////////////////////////////////////////////////////////////////
71 enum EscDir
{LKS
,RTS
,OBN
,UNT
};
82 SdrCaptionEscDir eEscDir
;
94 eEscDir
=SDRCAPT_ESCHORIZONTAL
;
101 void CalcEscPos(const Point
& rTail
, const Rectangle
& rRect
, Point
& rPt
, EscDir
& rDir
) const;
104 void ImpCaptParams::CalcEscPos(const Point
& rTailPt
, const Rectangle
& rRect
, Point
& rPt
, EscDir
& rDir
) const
106 Point
aTl(rTailPt
); // lokal kopieren wg. Performance
109 nX
=rRect
.Right()-rRect
.Left();
110 nX
=BigMulDiv(nX
,nEscRel
,10000);
111 nY
=rRect
.Bottom()-rRect
.Top();
112 nY
=BigMulDiv(nY
,nEscRel
,10000);
121 FASTBOOL bTryH
=eEscDir
==SDRCAPT_ESCBESTFIT
;
123 if (eType
!=SDRCAPT_TYPE1
) {
124 bTryH
=eEscDir
==SDRCAPT_ESCHORIZONTAL
;
126 bTryH
=eEscDir
==SDRCAPT_ESCVERTICAL
;
129 FASTBOOL bTryV
=eEscDir
==SDRCAPT_ESCBESTFIT
;
131 if (eType
!=SDRCAPT_TYPE1
) {
132 bTryV
=eEscDir
==SDRCAPT_ESCVERTICAL
;
134 bTryV
=eEscDir
==SDRCAPT_ESCHORIZONTAL
;
139 Point
aLft(rRect
.Left()-nGap
,nY
);
140 Point
aRgt(rRect
.Right()+nGap
,nY
);
141 FASTBOOL bLft
=(aTl
.X()-aLft
.X()<aRgt
.X()-aTl
.X());
151 Point
aTop(nX
,rRect
.Top()-nGap
);
152 Point
aBtm(nX
,rRect
.Bottom()+nGap
);
153 FASTBOOL bTop
=(aTl
.Y()-aTop
.Y()<aBtm
.Y()-aTl
.Y());
163 FASTBOOL bTakeIt
=eEscDir
!=SDRCAPT_ESCBESTFIT
;
165 BigInt
aHorX(aBestPt
.X()-aTl
.X()); aHorX
*=aHorX
;
166 BigInt
aHorY(aBestPt
.Y()-aTl
.Y()); aHorY
*=aHorY
;
167 BigInt
aVerX(aBest2
.X()-aTl
.X()); aVerX
*=aVerX
;
168 BigInt
aVerY(aBest2
.Y()-aTl
.Y()); aVerY
*=aVerY
;
169 if (eType
!=SDRCAPT_TYPE1
) {
170 bTakeIt
=aVerX
+aVerY
<aHorX
+aHorY
;
172 bTakeIt
=aVerX
+aVerY
>=aHorX
+aHorY
;
184 //////////////////////////////////////////////////////////////////////////////
185 // BaseProperties section
187 sdr::properties::BaseProperties
* SdrCaptionObj::CreateObjectSpecificProperties()
189 return new sdr::properties::CaptionProperties(*this);
192 //////////////////////////////////////////////////////////////////////////////
193 // DrawContact section
195 sdr::contact::ViewContact
* SdrCaptionObj::CreateObjectSpecificViewContact()
197 return new sdr::contact::ViewContactOfSdrCaptionObj(*this);
200 //////////////////////////////////////////////////////////////////////////////
202 TYPEINIT1(SdrCaptionObj
,SdrRectObj
);
204 SdrCaptionObj::SdrCaptionObj():
205 SdrRectObj(OBJ_TEXT
),
206 aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
207 mbSpecialTextBoxShadow(FALSE
),
212 SdrCaptionObj::SdrCaptionObj(const Rectangle
& rRect
):
213 SdrRectObj(OBJ_TEXT
,rRect
),
214 aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
215 mbSpecialTextBoxShadow(FALSE
),
220 SdrCaptionObj::SdrCaptionObj(const Rectangle
& rRect
, const Point
& rTail
):
221 SdrRectObj(OBJ_TEXT
,rRect
),
222 aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
223 mbSpecialTextBoxShadow(FALSE
),
226 aTailPoly
[0]=maFixedTailPos
=rTail
;
229 SdrCaptionObj::~SdrCaptionObj()
233 void SdrCaptionObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
235 rInfo
.bRotateFreeAllowed
=FALSE
;
236 rInfo
.bRotate90Allowed
=FALSE
;
237 rInfo
.bMirrorFreeAllowed
=FALSE
;
238 rInfo
.bMirror45Allowed
=FALSE
;
239 rInfo
.bMirror90Allowed
=FALSE
;
240 rInfo
.bTransparenceAllowed
= FALSE
;
241 rInfo
.bGradientAllowed
= FALSE
;
242 rInfo
.bShearAllowed
=FALSE
;
243 rInfo
.bEdgeRadiusAllowed
=FALSE
;
244 rInfo
.bCanConvToPath
=TRUE
;
245 rInfo
.bCanConvToPoly
=TRUE
;
246 rInfo
.bCanConvToPathLineToArea
=FALSE
;
247 rInfo
.bCanConvToPolyLineToArea
=FALSE
;
248 rInfo
.bCanConvToContour
= (rInfo
.bCanConvToPoly
|| LineGeometryUsageIsNecessary());
251 UINT16
SdrCaptionObj::GetObjIdentifier() const
253 return UINT16(OBJ_CAPTION
);
256 void SdrCaptionObj::operator=(const SdrObject
& rObj
)
258 SdrRectObj::operator=(rObj
);
259 aTailPoly
=((SdrCaptionObj
&)rObj
).aTailPoly
;
262 void SdrCaptionObj::TakeObjNameSingul(XubString
& rName
) const
264 rName
=ImpGetResStr(STR_ObjNameSingulCAPTION
);
266 String
aName( GetName() );
269 rName
+= sal_Unicode(' ');
270 rName
+= sal_Unicode('\'');
272 rName
+= sal_Unicode('\'');
276 void SdrCaptionObj::TakeObjNamePlural(XubString
& rName
) const
278 rName
=ImpGetResStr(STR_ObjNamePluralCAPTION
);
281 basegfx::B2DPolyPolygon
SdrCaptionObj::TakeXorPoly() const
283 basegfx::B2DPolyPolygon
aPolyPoly(SdrRectObj::TakeXorPoly());
284 aPolyPoly
.append(aTailPoly
.getB2DPolygon());
289 sal_uInt32
SdrCaptionObj::GetHdlCount() const
291 sal_uInt32
nAnz1(SdrRectObj::GetHdlCount());
292 // sal_uInt32 nAnz2(aTailPoly.GetSize());
293 // Derzeit ist nur das Draggen des Schwanzendes implementiert
297 SdrHdl
* SdrCaptionObj::GetHdl(sal_uInt32 nHdlNum
) const
299 const sal_uInt32
nRectHdlAnz(SdrRectObj::GetHdlCount());
301 if(nHdlNum
< nRectHdlAnz
)
303 return SdrRectObj::GetHdl(nHdlNum
);
307 sal_uInt32
nPntNum(nHdlNum
);
308 nPntNum
-= nRectHdlAnz
;
310 if(nPntNum
< aTailPoly
.GetSize())
312 SdrHdl
* pHdl
= new SdrHdl(aTailPoly
.GetPoint((sal_uInt16
)nPntNum
), HDL_POLY
);
313 pHdl
->SetPolyNum(1L);
314 pHdl
->SetPointNum(nPntNum
);
324 ////////////////////////////////////////////////////////////////////////////////////////////////////
326 bool SdrCaptionObj::hasSpecialDrag() const
331 bool SdrCaptionObj::beginSpecialDrag(SdrDragStat
& rDrag
) const
333 const SdrHdl
* pHdl
= rDrag
.GetHdl();
334 rDrag
.SetEndDragChangesAttributes(true);
335 rDrag
.SetEndDragChangesGeoAndAttributes(true);
337 if(pHdl
&& 0 == pHdl
->GetPolyNum())
339 return SdrRectObj::beginSpecialDrag(rDrag
);
343 rDrag
.SetOrtho8Possible(true);
350 rDrag
.SetNoSnap(true);
351 rDrag
.SetActionRect(aRect
);
353 Point
aHit(rDrag
.GetStart());
355 if(rDrag
.GetPageView() && SdrObjectPrimitiveHit(*this, aHit
, 0, *rDrag
.GetPageView(), 0, false))
362 if((1 == pHdl
->GetPolyNum()) && (0 == pHdl
->GetPointNum()))
370 bool SdrCaptionObj::applySpecialDrag(SdrDragStat
& rDrag
)
372 const SdrHdl
* pHdl
= rDrag
.GetHdl();
374 if(pHdl
&& 0 == pHdl
->GetPolyNum())
376 const bool bRet(SdrRectObj::applySpecialDrag(rDrag
));
384 Point
aDelt(rDrag
.GetNow()-rDrag
.GetStart());
388 aRect
.Move(aDelt
.X(),aDelt
.Y());
392 aTailPoly
[0] += aDelt
;
402 String
SdrCaptionObj::getSpecialDragComment(const SdrDragStat
& rDrag
) const
404 const bool bCreateComment(rDrag
.GetView() && this == rDrag
.GetView()->GetCreateObj());
412 const SdrHdl
* pHdl
= rDrag
.GetHdl();
414 if(pHdl
&& 0 == pHdl
->GetPolyNum())
416 return SdrRectObj::getSpecialDragComment(rDrag
);
424 ImpTakeDescriptionStr(STR_DragCaptFram
, aStr
);
428 ImpTakeDescriptionStr(STR_DragCaptTail
, aStr
);
436 ////////////////////////////////////////////////////////////////////////////////////////////////////
438 void SdrCaptionObj::ImpGetCaptParams(ImpCaptParams
& rPara
) const
440 const SfxItemSet
& rSet
= GetObjectItemSet();
441 rPara
.eType
=((SdrCaptionTypeItem
&) (rSet
.Get(SDRATTR_CAPTIONTYPE
))).GetValue();
442 rPara
.bFixedAngle
=((SdrCaptionFixedAngleItem
&)(rSet
.Get(SDRATTR_CAPTIONANGLE
))).GetValue();
443 rPara
.nAngle
=((SdrCaptionAngleItem
&) (rSet
.Get(SDRATTR_CAPTIONFIXEDANGLE
))).GetValue();
444 rPara
.nGap
=((SdrCaptionGapItem
&) (rSet
.Get(SDRATTR_CAPTIONGAP
))).GetValue();
445 rPara
.eEscDir
=((SdrCaptionEscDirItem
&) (rSet
.Get(SDRATTR_CAPTIONESCDIR
))).GetValue();
446 rPara
.bEscRel
=((SdrCaptionEscIsRelItem
&) (rSet
.Get(SDRATTR_CAPTIONESCISREL
))).GetValue();
447 rPara
.nEscRel
=((SdrCaptionEscRelItem
&) (rSet
.Get(SDRATTR_CAPTIONESCREL
))).GetValue();
448 rPara
.nEscAbs
=((SdrCaptionEscAbsItem
&) (rSet
.Get(SDRATTR_CAPTIONESCABS
))).GetValue();
449 rPara
.nLineLen
=((SdrCaptionLineLenItem
&) (rSet
.Get(SDRATTR_CAPTIONLINELEN
))).GetValue();
450 rPara
.bFitLineLen
=((SdrCaptionFitLineLenItem
&)(rSet
.Get(SDRATTR_CAPTIONFITLINELEN
))).GetValue();
453 void SdrCaptionObj::ImpRecalcTail()
456 ImpGetCaptParams(aPara
);
457 ImpCalcTail(aPara
,aTailPoly
,aRect
);
463 // SdrCaptionObj::ImpCalcTail1 does move the object(!). What a hack.
464 // I really wonder why this had not triggered problems before. I am
465 // sure there are some places where SetTailPos() is called at least
466 // twice or SetSnapRect after it again just to work around this.
467 // Changed this method to not do that.
468 // Also found why this has been done: For interactive dragging of the
469 // tail end pos for SDRCAPT_TYPE1. This sure was the simplest method
470 // to achieve this, for the cost to make a whole group of const methods
471 // of this object implicitly chainging the object's position.
472 void SdrCaptionObj::ImpCalcTail1(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
483 rPara
.CalcEscPos(aTl
, rRect
, aEscPos
, eEscDir
);
486 if(eEscDir
==LKS
|| eEscDir
==RTS
)
488 aPol
[0].X() = aEscPos
.X();
492 aPol
[0].Y() = aEscPos
.Y();
498 void SdrCaptionObj::ImpCalcTail2(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
499 { // Gap/EscDir/EscPos/Angle
506 rPara
.CalcEscPos(aTl
,rRect
,aEscPos
,eEscDir
);
509 if (!rPara
.bFixedAngle
) {
510 // fehlende Implementation
515 void SdrCaptionObj::ImpCalcTail3(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
516 { // Gap/EscDir/EscPos/Angle/LineLen
523 rPara
.CalcEscPos(aTl
,rRect
,aEscPos
,eEscDir
);
527 if (eEscDir
==LKS
|| eEscDir
==RTS
) {
528 if (rPara
.bFitLineLen
) {
529 aPol
[1].X()=(aTl
.X()+aEscPos
.X())/2;
531 if (eEscDir
==LKS
) aPol
[1].X()-=rPara
.nLineLen
;
532 else aPol
[1].X()+=rPara
.nLineLen
;
535 if (rPara
.bFitLineLen
) {
536 aPol
[1].Y()=(aTl
.Y()+aEscPos
.Y())/2;
538 if (eEscDir
==OBN
) aPol
[1].Y()-=rPara
.nLineLen
;
539 else aPol
[1].Y()+=rPara
.nLineLen
;
542 if (!rPara
.bFixedAngle
) {
543 // fehlende Implementation
548 void SdrCaptionObj::ImpCalcTail4(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
550 ImpCalcTail3(rPara
,rPoly
,rRect
);
553 void SdrCaptionObj::ImpCalcTail(const ImpCaptParams
& rPara
, Polygon
& rPoly
, Rectangle
& rRect
) const
555 switch (rPara
.eType
) {
556 case SDRCAPT_TYPE1
: ImpCalcTail1(rPara
,rPoly
,rRect
); break;
557 case SDRCAPT_TYPE2
: ImpCalcTail2(rPara
,rPoly
,rRect
); break;
558 case SDRCAPT_TYPE3
: ImpCalcTail3(rPara
,rPoly
,rRect
); break;
559 case SDRCAPT_TYPE4
: ImpCalcTail4(rPara
,rPoly
,rRect
); break;
563 FASTBOOL
SdrCaptionObj::BegCreate(SdrDragStat
& rStat
)
565 if (aRect
.IsEmpty()) return FALSE
; // Create z.Zt. nur mit vorgegebenen Rect
568 ImpGetCaptParams(aPara
);
569 aRect
.SetPos(rStat
.GetNow());
570 aTailPoly
[0]=rStat
.GetStart();
571 ImpCalcTail(aPara
,aTailPoly
,aRect
);
572 rStat
.SetActionRect(aRect
);
576 FASTBOOL
SdrCaptionObj::MovCreate(SdrDragStat
& rStat
)
579 ImpGetCaptParams(aPara
);
580 aRect
.SetPos(rStat
.GetNow());
581 ImpCalcTail(aPara
,aTailPoly
,aRect
);
582 rStat
.SetActionRect(aRect
);
588 FASTBOOL
SdrCaptionObj::EndCreate(SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
591 ImpGetCaptParams(aPara
);
592 aRect
.SetPos(rStat
.GetNow());
593 ImpCalcTail(aPara
,aTailPoly
,aRect
);
595 return (eCmd
==SDRCREATE_FORCEEND
|| rStat
.GetPointAnz()>=2);
598 FASTBOOL
SdrCaptionObj::BckCreate(SdrDragStat
& /*rStat*/)
603 void SdrCaptionObj::BrkCreate(SdrDragStat
& /*rStat*/)
607 basegfx::B2DPolyPolygon
SdrCaptionObj::TakeCreatePoly(const SdrDragStat
& /*rDrag*/) const
609 basegfx::B2DPolyPolygon aRetval
;
610 const basegfx::B2DRange
aRange(aRect
.Left(), aRect
.Top(), aRect
.Right(), aRect
.Bottom());
611 aRetval
.append(basegfx::tools::createPolygonFromRect(aRange
));
612 aRetval
.append(aTailPoly
.getB2DPolygon());
616 Pointer
SdrCaptionObj::GetCreatePointer() const
618 return Pointer(POINTER_DRAW_CAPTION
);
621 void SdrCaptionObj::NbcMove(const Size
& rSiz
)
623 SdrRectObj::NbcMove(rSiz
);
624 MovePoly(aTailPoly
,rSiz
);
626 SetTailPos(GetFixedTailPos());
629 void SdrCaptionObj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
631 SdrRectObj::NbcResize(rRef
,xFact
,yFact
);
632 ResizePoly(aTailPoly
,rRef
,xFact
,yFact
);
635 SetTailPos(GetFixedTailPos());
638 void SdrCaptionObj::NbcSetRelativePos(const Point
& rPnt
)
640 Point
aRelPos0(aTailPoly
.GetPoint(0)-aAnchor
);
641 Size
aSiz(rPnt
.X()-aRelPos0
.X(),rPnt
.Y()-aRelPos0
.Y());
642 NbcMove(aSiz
); // Der ruft auch das SetRectsDirty()
645 Point
SdrCaptionObj::GetRelativePos() const
647 return aTailPoly
.GetPoint(0)-aAnchor
;
650 void SdrCaptionObj::NbcSetAnchorPos(const Point
& rPnt
)
652 SdrRectObj::NbcSetAnchorPos(rPnt
);
653 // !!!!! fehlende Impl.
656 const Point
& SdrCaptionObj::GetAnchorPos() const
658 // !!!!! fehlende Impl.
659 return SdrRectObj::GetAnchorPos();
662 void SdrCaptionObj::RecalcSnapRect()
664 SdrRectObj::RecalcSnapRect();
666 // maSnapRect.Union(aTailPoly.GetBoundRect());
667 // !!!!! fehlende Impl.
670 const Rectangle
& SdrCaptionObj::GetSnapRect() const
672 return SdrRectObj::GetSnapRect();
675 void SdrCaptionObj::NbcSetSnapRect(const Rectangle
& rRect
)
678 // Move back to see the rectangle of the underlying SdrRectObj
679 // as the SnapRect, without the TailPos. That simplifies SnapRect
680 // handling again, if not allows it at all...
681 SdrRectObj::NbcSetSnapRect(rRect
);
684 const Rectangle
& SdrCaptionObj::GetLogicRect() const
689 void SdrCaptionObj::NbcSetLogicRect(const Rectangle
& rRect
)
691 SdrRectObj::NbcSetLogicRect(rRect
);
695 const Point
& SdrCaptionObj::GetTailPos() const
700 void SdrCaptionObj::SetTailPos(const Point
& rPos
)
702 if (aTailPoly
.GetSize()==0 || aTailPoly
[0]!=rPos
) {
703 Rectangle aBoundRect0
; if (pUserCall
!=NULL
) aBoundRect0
=GetLastBoundRect();
704 // #110094#-14 SendRepaintBroadcast();
707 BroadcastObjectChange();
708 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
712 void SdrCaptionObj::NbcSetTailPos(const Point
& rPos
)
718 sal_uInt32
SdrCaptionObj::GetSnapPointCount() const
720 // !!!!! fehlende Impl.
724 Point
SdrCaptionObj::GetSnapPoint(sal_uInt32
/*i*/) const
726 // !!!!! fehlende Impl.
730 void SdrCaptionObj::SetModel(SdrModel
* pNewModel
)
732 SdrRectObj::SetModel(pNewModel
);
736 void SdrCaptionObj::Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
738 SdrRectObj::Notify(rBC
,rHint
);
742 SdrObjGeoData
* SdrCaptionObj::NewGeoData() const
744 return new SdrCaptObjGeoData
;
747 void SdrCaptionObj::SaveGeoData(SdrObjGeoData
& rGeo
) const
749 SdrRectObj::SaveGeoData(rGeo
);
750 SdrCaptObjGeoData
& rCGeo
=(SdrCaptObjGeoData
&)rGeo
;
751 rCGeo
.aTailPoly
=aTailPoly
;
754 void SdrCaptionObj::RestGeoData(const SdrObjGeoData
& rGeo
)
756 SdrRectObj::RestGeoData(rGeo
);
757 SdrCaptObjGeoData
& rCGeo
=(SdrCaptObjGeoData
&)rGeo
;
758 aTailPoly
=rCGeo
.aTailPoly
;
761 SdrObject
* SdrCaptionObj::DoConvertToPolyObj(BOOL bBezier
) const
762 { // #42334# - Convert implementiert
763 SdrObject
* pRect
=SdrRectObj::DoConvertToPolyObj(bBezier
);
764 SdrObject
* pTail
= ImpConvertMakeObj(basegfx::B2DPolyPolygon(aTailPoly
.getB2DPolygon()), sal_False
, bBezier
);
765 SdrObject
* pRet
=(pTail
!=NULL
) ? pTail
: pRect
;
766 if (pTail
!=NULL
&& pRect
!=NULL
) {
767 FASTBOOL bInsRect
=TRUE
;
768 FASTBOOL bInsTail
=TRUE
;
769 SdrObjList
* pOL
=pTail
->GetSubList();
770 if (pOL
!=NULL
) { pRet
=pRect
; bInsTail
=FALSE
; }
771 if (pOL
==NULL
) pOL
=pRect
->GetSubList();
772 if (pOL
!=NULL
) { pRet
=pRect
; bInsRect
=FALSE
; }
774 SdrObjGroup
* pGrp
=new SdrObjGroup
;
775 pOL
=pGrp
->GetSubList();
778 if (bInsRect
) pOL
->NbcInsertObject(pRect
);
779 if (bInsTail
) pOL
->NbcInsertObject(pTail
,0);
785 // Add own implementation for TRSetBaseGeometry to handle TailPos over changes.
786 void SdrCaptionObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix
& rMatrix
, const basegfx::B2DPolyPolygon
& /*rPolyPolygon*/)
789 basegfx::B2DTuple aScale
;
790 basegfx::B2DTuple aTranslate
;
791 double fRotate
, fShearX
;
792 rMatrix
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
794 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
795 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
796 if(basegfx::fTools::less(aScale
.getX(), 0.0) && basegfx::fTools::less(aScale
.getY(), 0.0))
798 aScale
.setX(fabs(aScale
.getX()));
799 aScale
.setY(fabs(aScale
.getY()));
800 fRotate
= fmod(fRotate
+ F_PI
, F_2PI
);
803 // force metric to pool metric
804 SfxMapUnit eMapUnit
= pModel
->GetItemPool().GetMetric(0);
805 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
809 case SFX_MAPUNIT_TWIP
:
812 aTranslate
.setX(ImplMMToTwips(aTranslate
.getX()));
813 aTranslate
.setY(ImplMMToTwips(aTranslate
.getY()));
816 aScale
.setX(ImplMMToTwips(aScale
.getX()));
817 aScale
.setY(ImplMMToTwips(aScale
.getY()));
823 DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
828 // if anchor is used, make position relative to it
829 if( pModel
->IsWriter() )
831 if(GetAnchorPos().X() || GetAnchorPos().Y())
833 aTranslate
+= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
838 Point
aPoint(FRound(aTranslate
.getX()), FRound(aTranslate
.getY()));
839 Rectangle
aBaseRect(aPoint
, Size(FRound(aScale
.getX()), FRound(aScale
.getY())));
841 // set BaseRect, but rescue TailPos over this call
842 const Point aTailPoint
= GetTailPos();
843 SetSnapRect(aBaseRect
);
844 SetTailPos(aTailPoint
);
849 ::basegfx::B2DPolygon
SdrCaptionObj::getTailPolygon() const
851 return aTailPoly
.getB2DPolygon();