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