xref: /trunk/main/svx/source/svdraw/svdorect.cxx (revision 61dff127b6698e0bae836c8aedd6ec62111483d1)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <svx/svdorect.hxx>
32 #include <math.h>
33 #include <stdlib.h>
34 #include <svx/xpool.hxx>
35 #include <svx/xpoly.hxx>
36 #include <svx/svdattr.hxx>
37 #include <svx/svdpool.hxx>
38 #include <svx/svdtrans.hxx>
39 #include <svx/svdetc.hxx>
40 #include <svx/svddrag.hxx>
41 #include <svx/svdmodel.hxx>
42 #include <svx/svdpage.hxx>
43 #include <svx/svdocapt.hxx> // fuer Import von SdrFileVersion 2
44 #include <svx/svdpagv.hxx> // fuer
45 #include <svx/svdview.hxx> // das
46 #include <svx/svdundo.hxx> // Macro-Beispiel
47 #include <svx/svdopath.hxx>
48 #include "svx/svdglob.hxx"  // Stringcache
49 #include "svx/svdstr.hrc"   // Objektname
50 #include <svx/xflclit.hxx>
51 #include <svx/xlnclit.hxx>
52 #include <svx/xlnwtit.hxx>
53 #include "svdoimp.hxx"
54 #include <svx/sdr/properties/rectangleproperties.hxx>
55 #include <svx/sdr/contact/viewcontactofsdrrectobj.hxx>
56 #include <basegfx/polygon/b2dpolygon.hxx>
57 #include <basegfx/polygon/b2dpolygontools.hxx>
58 
59 //////////////////////////////////////////////////////////////////////////////
60 // BaseProperties section
61 
62 sdr::properties::BaseProperties* SdrRectObj::CreateObjectSpecificProperties()
63 {
64     return new sdr::properties::RectangleProperties(*this);
65 }
66 
67 //////////////////////////////////////////////////////////////////////////////
68 // DrawContact section
69 
70 sdr::contact::ViewContact* SdrRectObj::CreateObjectSpecificViewContact()
71 {
72     return new sdr::contact::ViewContactOfSdrRectObj(*this);
73 }
74 
75 //////////////////////////////////////////////////////////////////////////////
76 
77 TYPEINIT1(SdrRectObj,SdrTextObj);
78 
79 SdrRectObj::SdrRectObj()
80 :   mpXPoly(0L)
81 {
82     bClosedObj=sal_True;
83 }
84 
85 SdrRectObj::SdrRectObj(const Rectangle& rRect)
86 :   SdrTextObj(rRect),
87     mpXPoly(NULL)
88 {
89     bClosedObj=sal_True;
90 }
91 
92 SdrRectObj::SdrRectObj(SdrObjKind eNewTextKind)
93 :   SdrTextObj(eNewTextKind),
94     mpXPoly(NULL)
95 {
96     DBG_ASSERT(eTextKind==OBJ_TEXT || eTextKind==OBJ_TEXTEXT ||
97                eTextKind==OBJ_OUTLINETEXT || eTextKind==OBJ_TITLETEXT,
98                "SdrRectObj::SdrRectObj(SdrObjKind) ist nur fuer Textrahmen gedacht");
99     bClosedObj=sal_True;
100 }
101 
102 SdrRectObj::SdrRectObj(SdrObjKind eNewTextKind, const Rectangle& rRect)
103 :   SdrTextObj(eNewTextKind,rRect),
104     mpXPoly(NULL)
105 {
106     DBG_ASSERT(eTextKind==OBJ_TEXT || eTextKind==OBJ_TEXTEXT ||
107                eTextKind==OBJ_OUTLINETEXT || eTextKind==OBJ_TITLETEXT,
108                "SdrRectObj::SdrRectObj(SdrObjKind,...) ist nur fuer Textrahmen gedacht");
109     bClosedObj=sal_True;
110 }
111 
112 SdrRectObj::SdrRectObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect, SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
113 :    SdrTextObj(eNewTextKind,rNewRect,rInput,rBaseURL,eFormat),
114     mpXPoly(NULL)
115 {
116     DBG_ASSERT(eTextKind==OBJ_TEXT || eTextKind==OBJ_TEXTEXT ||
117                eTextKind==OBJ_OUTLINETEXT || eTextKind==OBJ_TITLETEXT,
118                "SdrRectObj::SdrRectObj(SdrObjKind,...) ist nur fuer Textrahmen gedacht");
119     bClosedObj=sal_True;
120 }
121 
122 SdrRectObj::~SdrRectObj()
123 {
124     if(mpXPoly)
125     {
126         delete mpXPoly;
127     }
128 }
129 
130 void SdrRectObj::SetXPolyDirty()
131 {
132     if(mpXPoly)
133     {
134         delete mpXPoly;
135         mpXPoly = 0L;
136     }
137 }
138 
139 FASTBOOL SdrRectObj::PaintNeedsXPoly(long nEckRad) const
140 {
141     FASTBOOL bNeed=aGeo.nDrehWink!=0 || aGeo.nShearWink!=0 || nEckRad!=0;
142     return bNeed;
143 }
144 
145 XPolygon SdrRectObj::ImpCalcXPoly(const Rectangle& rRect1, long nRad1) const
146 {
147     XPolygon aXPoly(rRect1,nRad1,nRad1);
148     const sal_uInt16 nPointAnz(aXPoly.GetPointCount());
149     XPolygon aNeuPoly(nPointAnz+1);
150     sal_uInt16 nShift=nPointAnz-2;
151     if (nRad1!=0) nShift=nPointAnz-5;
152     sal_uInt16 j=nShift;
153     for (sal_uInt16 i=1; i<nPointAnz; i++) {
154         aNeuPoly[i]=aXPoly[j];
155         aNeuPoly.SetFlags(i,aXPoly.GetFlags(j));
156         j++;
157         if (j>=nPointAnz) j=1;
158     }
159     aNeuPoly[0]=rRect1.BottomCenter();
160     aNeuPoly[nPointAnz]=aNeuPoly[0];
161     aXPoly=aNeuPoly;
162 
163     // Die Winkelangaben beziehen sich immer auf die linke obere Ecke von !aRect!
164     if (aGeo.nShearWink!=0) ShearXPoly(aXPoly,aRect.TopLeft(),aGeo.nTan);
165     if (aGeo.nDrehWink!=0) RotateXPoly(aXPoly,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
166     return aXPoly;
167 }
168 
169 void SdrRectObj::RecalcXPoly()
170 {
171     mpXPoly = new XPolygon(ImpCalcXPoly(aRect,GetEckenradius()));
172 }
173 
174 const XPolygon& SdrRectObj::GetXPoly() const
175 {
176     if(!mpXPoly)
177     {
178         ((SdrRectObj*)this)->RecalcXPoly();
179     }
180 
181     return *mpXPoly;
182 }
183 
184 void SdrRectObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
185 {
186     FASTBOOL bNoTextFrame=!IsTextFrame();
187     rInfo.bResizeFreeAllowed=bNoTextFrame || aGeo.nDrehWink%9000==0;
188     rInfo.bResizePropAllowed=sal_True;
189     rInfo.bRotateFreeAllowed=sal_True;
190     rInfo.bRotate90Allowed  =sal_True;
191     rInfo.bMirrorFreeAllowed=bNoTextFrame;
192     rInfo.bMirror45Allowed  =bNoTextFrame;
193     rInfo.bMirror90Allowed  =bNoTextFrame;
194 
195     // allow transparence
196     rInfo.bTransparenceAllowed = sal_True;
197 
198     // gradient depends on fillstyle
199     XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
200     rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
201 
202     rInfo.bShearAllowed     =bNoTextFrame;
203     rInfo.bEdgeRadiusAllowed=sal_True;
204 
205     FASTBOOL bCanConv=!HasText() || ImpCanConvTextToCurve();
206     if (bCanConv && !bNoTextFrame && !HasText()) {
207         bCanConv=HasFill() || HasLine();
208     }
209     rInfo.bCanConvToPath    =bCanConv;
210     rInfo.bCanConvToPoly    =bCanConv;
211     rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
212 }
213 
214 sal_uInt16 SdrRectObj::GetObjIdentifier() const
215 {
216     if (IsTextFrame()) return sal_uInt16(eTextKind);
217     else return sal_uInt16(OBJ_RECT);
218 }
219 
220 void SdrRectObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
221 {
222     rRect=aRect;
223     if (aGeo.nShearWink!=0) {
224         long nDst=Round((aRect.Bottom()-aRect.Top())*aGeo.nTan);
225         if (aGeo.nShearWink>0) {
226             Point aRef(rRect.TopLeft());
227             rRect.Left()-=nDst;
228             Point aTmpPt(rRect.TopLeft());
229             RotatePoint(aTmpPt,aRef,aGeo.nSin,aGeo.nCos);
230             aTmpPt-=rRect.TopLeft();
231             rRect.Move(aTmpPt.X(),aTmpPt.Y());
232         } else {
233             rRect.Right()-=nDst;
234         }
235     }
236 }
237 
238 void SdrRectObj::TakeObjNameSingul(XubString& rName) const
239 {
240     if (IsTextFrame())
241     {
242         SdrTextObj::TakeObjNameSingul(rName);
243     }
244     else
245     {
246         sal_uInt16 nResId=STR_ObjNameSingulRECT;
247         if (aGeo.nShearWink!=0) {
248             nResId+=4;  // Parallelogramm oder Raute
249             // Raute ist nicht, weil Shear die vertikalen Kanten verlaengert!
250             // Wenn Zeit ist, werde ich das mal berechnen.
251         } else {
252             if (aRect.GetWidth()==aRect.GetHeight()) nResId+=2; // Quadrat
253         }
254         if (GetEckenradius()!=0) nResId+=8; // abgerundet
255         rName=ImpGetResStr(nResId);
256 
257         String aName( GetName() );
258         if(aName.Len())
259         {
260             rName += sal_Unicode(' ');
261             rName += sal_Unicode('\'');
262             rName += aName;
263             rName += sal_Unicode('\'');
264         }
265     }
266 }
267 
268 void SdrRectObj::TakeObjNamePlural(XubString& rName) const
269 {
270     if (IsTextFrame()) SdrTextObj::TakeObjNamePlural(rName);
271     else {
272         sal_uInt16 nResId=STR_ObjNamePluralRECT;
273         if (aGeo.nShearWink!=0) {
274             nResId+=4;  // Parallelogramm oder Raute
275         } else {
276             if (aRect.GetWidth()==aRect.GetHeight()) nResId+=2; // Quadrat
277         }
278         if (GetEckenradius()!=0) nResId+=8; // abgerundet
279         rName=ImpGetResStr(nResId);
280     }
281 }
282 
283 void SdrRectObj::operator=(const SdrObject& rObj)
284 {
285     SdrTextObj::operator=(rObj);
286 }
287 
288 basegfx::B2DPolyPolygon SdrRectObj::TakeXorPoly() const
289 {
290     XPolyPolygon aXPP;
291     aXPP.Insert(ImpCalcXPoly(aRect,GetEckenradius()));
292     return aXPP.getB2DPolyPolygon();
293 }
294 
295 void SdrRectObj::RecalcSnapRect()
296 {
297     long nEckRad=GetEckenradius();
298     if ((aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) && nEckRad!=0) {
299         maSnapRect=GetXPoly().GetBoundRect();
300     } else {
301         SdrTextObj::RecalcSnapRect();
302     }
303 }
304 
305 void SdrRectObj::NbcSetSnapRect(const Rectangle& rRect)
306 {
307     SdrTextObj::NbcSetSnapRect(rRect);
308     SetXPolyDirty();
309 }
310 
311 void SdrRectObj::NbcSetLogicRect(const Rectangle& rRect)
312 {
313     SdrTextObj::NbcSetLogicRect(rRect);
314     SetXPolyDirty();
315 }
316 
317 sal_uInt32 SdrRectObj::GetHdlCount() const
318 {
319     return IsTextFrame() ? 10 : 9;
320 }
321 
322 SdrHdl* SdrRectObj::GetHdl(sal_uInt32 nHdlNum) const
323 {
324     SdrHdl* pH = NULL;
325     Point aPnt;
326     SdrHdlKind eKind = HDL_MOVE;
327 
328     if(!IsTextFrame())
329     {
330         nHdlNum++;
331     }
332 
333     switch(nHdlNum)
334     {
335         case 0:
336         {
337             pH = new ImpTextframeHdl(aRect);
338             pH->SetObj((SdrObject*)this);
339             pH->SetDrehWink(aGeo.nDrehWink);
340             break;
341         }
342         case 1:
343         {
344             long a = GetEckenradius();
345             long b = Max(aRect.GetWidth(),aRect.GetHeight())/2; // Wird aufgerundet, da GetWidth() eins draufaddiert
346             if (a>b) a=b;
347             if (a<0) a=0;
348             aPnt=aRect.TopLeft();
349             aPnt.X()+=a;
350             eKind = HDL_CIRC;
351             break;
352         }
353         case 2: aPnt=aRect.TopLeft();      eKind = HDL_UPLFT; break; // Oben links
354         case 3: aPnt=aRect.TopCenter();    eKind = HDL_UPPER; break; // Oben
355         case 4: aPnt=aRect.TopRight();     eKind = HDL_UPRGT; break; // Oben rechts
356         case 5: aPnt=aRect.LeftCenter();   eKind = HDL_LEFT ; break; // Links
357         case 6: aPnt=aRect.RightCenter();  eKind = HDL_RIGHT; break; // Rechts
358         case 7: aPnt=aRect.BottomLeft();   eKind = HDL_LWLFT; break; // Unten links
359         case 8: aPnt=aRect.BottomCenter(); eKind = HDL_LOWER; break; // Unten
360         case 9: aPnt=aRect.BottomRight();  eKind = HDL_LWRGT; break; // Unten rechts
361     }
362 
363     if(!pH)
364     {
365         if(aGeo.nShearWink)
366         {
367             ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan);
368         }
369 
370         if(aGeo.nDrehWink)
371         {
372             RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
373         }
374 
375         pH = new SdrHdl(aPnt,eKind);
376         pH->SetObj((SdrObject*)this);
377         pH->SetDrehWink(aGeo.nDrehWink);
378     }
379 
380     return pH;
381 }
382 
383 ////////////////////////////////////////////////////////////////////////////////////////////////////
384 
385 bool SdrRectObj::hasSpecialDrag() const
386 {
387     return true;
388 }
389 
390 bool SdrRectObj::beginSpecialDrag(SdrDragStat& rDrag) const
391 {
392     const bool bRad(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
393 
394     if(bRad)
395     {
396         rDrag.SetEndDragChangesAttributes(true);
397 
398         return true;
399     }
400 
401     return SdrTextObj::beginSpecialDrag(rDrag);
402 }
403 
404 bool SdrRectObj::applySpecialDrag(SdrDragStat& rDrag)
405 {
406     const bool bRad(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
407 
408     if (bRad)
409     {
410         Rectangle aBoundRect0;
411         Point aPt(rDrag.GetNow());
412 
413         if(aGeo.nDrehWink)
414             RotatePoint(aPt,aRect.TopLeft(),-aGeo.nSin,aGeo.nCos);
415 
416         sal_Int32 nRad(aPt.X() - aRect.Left());
417 
418         if (nRad < 0)
419             nRad = 0;
420 
421         if(nRad != GetEckenradius())
422         {
423             NbcSetEckenradius(nRad);
424         }
425 
426         return true;
427     }
428     else
429     {
430         return SdrTextObj::applySpecialDrag(rDrag);
431     }
432 }
433 
434 String SdrRectObj::getSpecialDragComment(const SdrDragStat& rDrag) const
435 {
436     const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
437 
438     if(bCreateComment)
439     {
440         return String();
441     }
442     else
443     {
444         const bool bRad(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
445 
446         if(bRad)
447         {
448             Point aPt(rDrag.GetNow());
449 
450             // -sin fuer Umkehrung
451             if(aGeo.nDrehWink)
452                 RotatePoint(aPt, aRect.TopLeft(), -aGeo.nSin, aGeo.nCos);
453 
454             sal_Int32 nRad(aPt.X() - aRect.Left());
455 
456             if(nRad < 0)
457                 nRad = 0;
458 
459             XubString aStr;
460 
461             ImpTakeDescriptionStr(STR_DragRectEckRad, aStr);
462             aStr.AppendAscii(" (");
463             aStr += GetMetrStr(nRad);
464             aStr += sal_Unicode(')');
465 
466             return aStr;
467         }
468         else
469         {
470             return SdrTextObj::getSpecialDragComment(rDrag);
471         }
472     }
473 }
474 
475 ////////////////////////////////////////////////////////////////////////////////////////////////////
476 
477 basegfx::B2DPolyPolygon SdrRectObj::TakeCreatePoly(const SdrDragStat& rDrag) const
478 {
479     Rectangle aRect1;
480     rDrag.TakeCreateRect(aRect1);
481     aRect1.Justify();
482 
483     basegfx::B2DPolyPolygon aRetval;
484     aRetval.append(ImpCalcXPoly(aRect1,GetEckenradius()).getB2DPolygon());
485     return aRetval;
486 }
487 
488 Pointer SdrRectObj::GetCreatePointer() const
489 {
490     if (IsTextFrame()) return Pointer(POINTER_DRAW_TEXT);
491     return Pointer(POINTER_DRAW_RECT);
492 }
493 
494 void SdrRectObj::NbcMove(const Size& rSiz)
495 {
496     SdrTextObj::NbcMove(rSiz);
497     SetXPolyDirty();
498 }
499 
500 void SdrRectObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
501 {
502     SdrTextObj::NbcResize(rRef,xFact,yFact);
503     SetXPolyDirty();
504 }
505 
506 void SdrRectObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
507 {
508     SdrTextObj::NbcRotate(rRef,nWink,sn,cs);
509     SetXPolyDirty();
510 }
511 
512 void SdrRectObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
513 {
514     SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
515     SetXPolyDirty();
516 }
517 
518 void SdrRectObj::NbcMirror(const Point& rRef1, const Point& rRef2)
519 {
520     SdrTextObj::NbcMirror(rRef1,rRef2);
521     SetXPolyDirty();
522 }
523 
524 FASTBOOL SdrRectObj::DoMacro(const SdrObjMacroHitRec& rRec)
525 {
526     return SdrTextObj::DoMacro(rRec);
527 }
528 
529 XubString SdrRectObj::GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const
530 {
531     return SdrTextObj::GetMacroPopupComment(rRec);
532 }
533 
534 SdrGluePoint SdrRectObj::GetVertexGluePoint(sal_uInt16 nPosNum) const
535 {
536     sal_Int32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
537 
538     // #i25616#
539     if(!LineIsOutsideGeometry())
540     {
541         nWdt++;
542         nWdt /= 2;
543     }
544 
545     Point aPt;
546     switch (nPosNum) {
547         case 0: aPt=aRect.TopCenter();    aPt.Y()-=nWdt; break;
548         case 1: aPt=aRect.RightCenter();  aPt.X()+=nWdt; break;
549         case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break;
550         case 3: aPt=aRect.LeftCenter();   aPt.X()-=nWdt; break;
551     }
552     if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
553     if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
554     aPt-=GetSnapRect().Center();
555     SdrGluePoint aGP(aPt);
556     aGP.SetPercent(sal_False);
557     return aGP;
558 }
559 
560 SdrGluePoint SdrRectObj::GetCornerGluePoint(sal_uInt16 nPosNum) const
561 {
562     sal_Int32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
563 
564     // #i25616#
565     if(!LineIsOutsideGeometry())
566     {
567         nWdt++;
568         nWdt /= 2;
569     }
570 
571     Point aPt;
572     switch (nPosNum) {
573         case 0: aPt=aRect.TopLeft();     aPt.X()-=nWdt; aPt.Y()-=nWdt; break;
574         case 1: aPt=aRect.TopRight();    aPt.X()+=nWdt; aPt.Y()-=nWdt; break;
575         case 2: aPt=aRect.BottomRight(); aPt.X()+=nWdt; aPt.Y()+=nWdt; break;
576         case 3: aPt=aRect.BottomLeft();  aPt.X()-=nWdt; aPt.Y()+=nWdt; break;
577     }
578     if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
579     if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
580     aPt-=GetSnapRect().Center();
581     SdrGluePoint aGP(aPt);
582     aGP.SetPercent(sal_False);
583     return aGP;
584 }
585 
586 SdrObject* SdrRectObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
587 {
588     XPolygon aXP(ImpCalcXPoly(aRect,GetEckenradius()));
589     { // #40608# Nur Uebergangsweise bis zum neuen TakeContour()
590         aXP.Remove(0,1);
591         aXP[aXP.GetPointCount()-1]=aXP[0];
592     }
593 
594     basegfx::B2DPolyPolygon aPolyPolygon(aXP.getB2DPolygon());
595     aPolyPolygon.removeDoublePoints();
596     SdrObject* pRet = 0L;
597 
598     if(!IsTextFrame() || HasFill() || HasLine())
599     {
600         pRet = ImpConvertMakeObj(aPolyPolygon, sal_True, bBezier);
601     }
602 
603     if(bAddText)
604     {
605         pRet = ImpConvertAddText(pRet, bBezier);
606     }
607 
608     return pRet;
609 }
610 
611 void SdrRectObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
612 {
613     SdrTextObj::Notify(rBC,rHint);
614     SetXPolyDirty(); // wg. Eckenradius
615 }
616 
617 void SdrRectObj::RestGeoData(const SdrObjGeoData& rGeo)
618 {
619     SdrTextObj::RestGeoData(rGeo);
620     SetXPolyDirty();
621 }
622 
623 // eof
624