xref: /AOO41X/main/svx/source/svdraw/svdotext.cxx (revision 9dc4e1a12052c64a43aee9442268e9bf519868aa)
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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include <svx/svdotext.hxx>
28 #include "svx/svditext.hxx"
29 #include <svx/svdpagv.hxx>  // fuer Abfrage im Paint, ob das
30 #include <svx/svdview.hxx>  // Objekt gerade editiert wird
31 #include <svx/svdpage.hxx>  // und fuer AnimationHandler (Laufschrift)
32 #include <svx/svdetc.hxx>
33 #include <svx/svdoutl.hxx>
34 #include <svx/svdmodel.hxx>  // OutlinerDefaults
35 #include "svx/svdglob.hxx"  // Stringcache
36 #include "svx/svdstr.hrc"   // Objektname
37 #include <editeng/writingmodeitem.hxx>
38 #include <svx/sdtfchim.hxx>
39 #include <svtools/colorcfg.hxx>
40 #include <editeng/eeitem.hxx>
41 #include <editeng/editstat.hxx>
42 #include <editeng/outlobj.hxx>
43 #include <editeng/editobj.hxx>
44 #include <editeng/outliner.hxx>
45 #include <editeng/fhgtitem.hxx>
46 #include <svl/itempool.hxx>
47 #include <editeng/adjitem.hxx>
48 #include <editeng/flditem.hxx>
49 #include <svx/xftouit.hxx>
50 #include <vcl/salbtype.hxx>     // FRound
51 #include <svx/xflgrit.hxx>
52 #include <svx/svdpool.hxx>
53 #include <svx/xflclit.hxx>
54 #include <svl/style.hxx>
55 #include <editeng/editeng.hxx>
56 #include <svl/itemiter.hxx>
57 #include <svx/sdr/properties/textproperties.hxx>
58 #include <vcl/metaact.hxx>
59 #include <svx/sdr/contact/viewcontactoftextobj.hxx>
60 #include <basegfx/tuple/b2dtuple.hxx>
61 #include <basegfx/matrix/b2dhommatrix.hxx>
62 #include <basegfx/polygon/b2dpolygon.hxx>
63 #include <drawinglayer/geometry/viewinformation2d.hxx>
64 #include <vcl/virdev.hxx>
65 #include <basegfx/matrix/b2dhommatrixtools.hxx>
66 
67 //////////////////////////////////////////////////////////////////////////////
68 
69 using namespace com::sun::star;
70 
71 //////////////////////////////////////////////////////////////////////////////
72 // #104018# replace macros above with type-safe methods
ImplTwipsToMM(double fVal)73 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
ImplMMToTwips(double fVal)74 inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
75 
76 ////////////////////////////////////////////////////////////////////////////////////////////////////
77 //
78 //  @@@@@@ @@@@@ @@   @@ @@@@@@  @@@@  @@@@@  @@@@@@
79 //    @@   @@    @@@ @@@   @@   @@  @@ @@  @@     @@
80 //    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
81 //    @@   @@@@    @@@     @@   @@  @@ @@@@@      @@
82 //    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
83 //    @@   @@    @@@ @@@   @@   @@  @@ @@  @@ @@  @@
84 //    @@   @@@@@ @@   @@   @@    @@@@  @@@@@   @@@@
85 //
86 ////////////////////////////////////////////////////////////////////////////////////////////////////
87 
88 //////////////////////////////////////////////////////////////////////////////
89 // BaseProperties section
90 
CreateObjectSpecificProperties()91 sdr::properties::BaseProperties* SdrTextObj::CreateObjectSpecificProperties()
92 {
93     return new sdr::properties::TextProperties(*this);
94 }
95 
96 //////////////////////////////////////////////////////////////////////////////
97 // DrawContact section
98 
CreateObjectSpecificViewContact()99 sdr::contact::ViewContact* SdrTextObj::CreateObjectSpecificViewContact()
100 {
101     return new sdr::contact::ViewContactOfTextObj(*this);
102 }
103 
104 //////////////////////////////////////////////////////////////////////////////
105 
106 TYPEINIT1(SdrTextObj,SdrAttrObj);
107 
SdrTextObj()108 SdrTextObj::SdrTextObj()
109 :   SdrAttrObj(),
110     mpText(NULL),
111     pEdtOutl(NULL),
112     pFormTextBoundRect(NULL),
113     eTextKind(OBJ_TEXT)
114 {
115     bTextSizeDirty=sal_False;
116     bTextFrame=sal_False;
117     bNoShear=sal_False;
118     bNoRotate=sal_False;
119     bNoMirror=sal_False;
120     bDisableAutoWidthOnDragging=sal_False;
121 
122     // #101684#
123     mbInEditMode = sal_False;
124 
125     // #111096#
126     mbTextHidden = sal_False;
127 
128     // #111096#
129     mbTextAnimationAllowed = sal_True;
130 
131     // #108784#
132     maTextEditOffset = Point(0, 0);
133 
134     // #i25616#
135     mbSupportTextIndentingOnLineWidthChange = sal_True;
136 }
137 
SdrTextObj(const Rectangle & rNewRect)138 SdrTextObj::SdrTextObj(const Rectangle& rNewRect)
139 :   SdrAttrObj(),
140     aRect(rNewRect),
141     mpText(NULL),
142     pEdtOutl(NULL),
143     pFormTextBoundRect(NULL)
144 {
145     bTextSizeDirty=sal_False;
146     bTextFrame=sal_False;
147     bNoShear=sal_False;
148     bNoRotate=sal_False;
149     bNoMirror=sal_False;
150     bDisableAutoWidthOnDragging=sal_False;
151     ImpJustifyRect(aRect);
152 
153     // #101684#
154     mbInEditMode = sal_False;
155 
156     // #111096#
157     mbTextHidden = sal_False;
158 
159     // #111096#
160     mbTextAnimationAllowed = sal_True;
161 
162     // #108784#
163     maTextEditOffset = Point(0, 0);
164 
165     // #i25616#
166     mbSupportTextIndentingOnLineWidthChange = sal_True;
167 }
168 
SdrTextObj(SdrObjKind eNewTextKind)169 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind)
170 :   SdrAttrObj(),
171     mpText(NULL),
172     pEdtOutl(NULL),
173     pFormTextBoundRect(NULL),
174     eTextKind(eNewTextKind)
175 {
176     bTextSizeDirty=sal_False;
177     bTextFrame=sal_True;
178     bNoShear=sal_True;
179     bNoRotate=sal_False;
180     bNoMirror=sal_True;
181     bDisableAutoWidthOnDragging=sal_False;
182 
183     // #101684#
184     mbInEditMode = sal_False;
185 
186     // #111096#
187     mbTextHidden = sal_False;
188 
189     // #111096#
190     mbTextAnimationAllowed = sal_True;
191 
192     // #108784#
193     maTextEditOffset = Point(0, 0);
194 
195     // #i25616#
196     mbSupportTextIndentingOnLineWidthChange = sal_True;
197 }
198 
SdrTextObj(SdrObjKind eNewTextKind,const Rectangle & rNewRect)199 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect)
200 :   SdrAttrObj(),
201     aRect(rNewRect),
202     mpText(NULL),
203     pEdtOutl(NULL),
204     pFormTextBoundRect(NULL),
205     eTextKind(eNewTextKind)
206 {
207     bTextSizeDirty=sal_False;
208     bTextFrame=sal_True;
209     bNoShear=sal_True;
210     bNoRotate=sal_False;
211     bNoMirror=sal_True;
212     bDisableAutoWidthOnDragging=sal_False;
213     ImpJustifyRect(aRect);
214 
215     // #101684#
216     mbInEditMode = sal_False;
217 
218     // #111096#
219     mbTextHidden = sal_False;
220 
221     // #111096#
222     mbTextAnimationAllowed = sal_True;
223 
224     // #108784#
225     maTextEditOffset = Point(0, 0);
226 
227     // #i25616#
228     mbSupportTextIndentingOnLineWidthChange = sal_True;
229 }
230 
SdrTextObj(SdrObjKind eNewTextKind,const Rectangle & rNewRect,SvStream & rInput,const String & rBaseURL,sal_uInt16 eFormat)231 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect, SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
232 :   SdrAttrObj(),
233     aRect(rNewRect),
234     mpText(NULL),
235     pEdtOutl(NULL),
236     pFormTextBoundRect(NULL),
237     eTextKind(eNewTextKind)
238 {
239     bTextSizeDirty=sal_False;
240     bTextFrame=sal_True;
241     bNoShear=sal_True;
242     bNoRotate=sal_False;
243     bNoMirror=sal_True;
244     bDisableAutoWidthOnDragging=sal_False;
245     ImpJustifyRect(aRect);
246 
247     NbcSetText(rInput, rBaseURL, eFormat);
248 
249     // #101684#
250     mbInEditMode = sal_False;
251 
252     // #111096#
253     mbTextHidden = sal_False;
254 
255     // #111096#
256     mbTextAnimationAllowed = sal_True;
257 
258     // #108784#
259     maTextEditOffset = Point(0, 0);
260 
261     // #i25616#
262     mbSupportTextIndentingOnLineWidthChange = sal_True;
263 }
264 
~SdrTextObj()265 SdrTextObj::~SdrTextObj()
266 {
267     if( pModel )
268     {
269         SdrOutliner& rOutl = pModel->GetHitTestOutliner();
270         if( rOutl.GetTextObj() == this )
271             rOutl.SetTextObj( NULL );
272     }
273 
274     if(mpText!=NULL)
275         delete mpText;
276 
277     if (pFormTextBoundRect!=NULL)
278         delete pFormTextBoundRect;
279 
280     ImpLinkAbmeldung();
281 }
282 
FitFrameToTextSize()283 void SdrTextObj::FitFrameToTextSize()
284 {
285     DBG_ASSERT(pModel!=NULL,"SdrTextObj::FitFrameToTextSize(): pModel=NULL!");
286     ImpJustifyRect(aRect);
287 
288     SdrText* pText = getActiveText();
289     if( pText!=NULL && pText->GetOutlinerParaObject() && pModel!=NULL)
290     {
291         SdrOutliner& rOutliner=ImpGetDrawOutliner();
292         rOutliner.SetPaperSize(Size(aRect.Right()-aRect.Left(),aRect.Bottom()-aRect.Top()));
293         rOutliner.SetUpdateMode(sal_True);
294         rOutliner.SetText(*pText->GetOutlinerParaObject());
295         Rectangle aTextRect;
296         Size aNewSize(rOutliner.CalcTextSize());
297         rOutliner.Clear();
298         aNewSize.Width()++; // wegen evtl. Rundungsfehler
299         aNewSize.Width()+=GetTextLeftDistance()+GetTextRightDistance();
300         aNewSize.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
301         Rectangle aNewRect(aRect);
302         aNewRect.SetSize(aNewSize);
303         ImpJustifyRect(aNewRect);
304         if (aNewRect!=aRect) {
305             SetLogicRect(aNewRect);
306         }
307     }
308 }
309 
NbcSetText(const XubString & rStr)310 void SdrTextObj::NbcSetText(const XubString& rStr)
311 {
312     SdrOutliner& rOutliner=ImpGetDrawOutliner();
313     rOutliner.SetStyleSheet( 0, GetStyleSheet());
314     //OutputDevice* pRef1=rOutliner.GetRefDevice();
315     rOutliner.SetUpdateMode(sal_True);
316     rOutliner.SetText(rStr,rOutliner.GetParagraph( 0 ));
317     OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
318     Size aSiz(rOutliner.CalcTextSize());
319     //OutputDevice* pRef2=rOutliner.GetRefDevice();
320     rOutliner.Clear();
321     NbcSetOutlinerParaObject(pNewText);
322     aTextSize=aSiz;
323     bTextSizeDirty=sal_False;
324 }
325 
SetText(const XubString & rStr)326 void SdrTextObj::SetText(const XubString& rStr)
327 {
328     Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
329     // #110094#-14 SendRepaintBroadcast();
330     NbcSetText(rStr);
331     SetChanged();
332     BroadcastObjectChange();
333     SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
334     //if (GetBoundRect()!=aBoundRect0) {
335     //  SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
336     //}
337 }
338 
NbcSetText(SvStream & rInput,const String & rBaseURL,sal_uInt16 eFormat)339 void SdrTextObj::NbcSetText(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
340 {
341     SdrOutliner& rOutliner=ImpGetDrawOutliner();
342     rOutliner.SetStyleSheet( 0, GetStyleSheet());
343     rOutliner.Read(rInput,rBaseURL,eFormat);
344     OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
345     rOutliner.SetUpdateMode(sal_True);
346     Size aSiz(rOutliner.CalcTextSize());
347     rOutliner.Clear();
348     NbcSetOutlinerParaObject(pNewText);
349     aTextSize=aSiz;
350     bTextSizeDirty=sal_False;
351 }
352 
SetText(SvStream & rInput,const String & rBaseURL,sal_uInt16 eFormat)353 void SdrTextObj::SetText(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
354 {
355     Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
356     // #110094#-14 SendRepaintBroadcast();
357     NbcSetText(rInput,rBaseURL,eFormat);
358     SetChanged();
359     BroadcastObjectChange();
360     SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
361 }
362 
GetTextSize() const363 const Size& SdrTextObj::GetTextSize() const
364 {
365     if (bTextSizeDirty)
366     {
367         Size aSiz;
368         SdrText* pText = getActiveText();
369         if( pText && pText->GetOutlinerParaObject ())
370         {
371             SdrOutliner& rOutliner=ImpGetDrawOutliner();
372             rOutliner.SetText(*pText->GetOutlinerParaObject());
373             rOutliner.SetUpdateMode(sal_True);
374             aSiz=rOutliner.CalcTextSize();
375             rOutliner.Clear();
376         }
377         // 2x casting auf nonconst
378         ((SdrTextObj*)this)->aTextSize=aSiz;
379         ((SdrTextObj*)this)->bTextSizeDirty=sal_False;
380     }
381     return aTextSize;
382 }
383 
IsAutoGrowHeight() const384 FASTBOOL SdrTextObj::IsAutoGrowHeight() const
385 {
386     if(!bTextFrame)
387         return sal_False; // AutoGrow nur bei TextFrames
388 
389     const SfxItemSet& rSet = GetObjectItemSet();
390     sal_Bool bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
391 
392     if(bRet)
393     {
394         SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
395 
396         if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
397         {
398             SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
399 
400             if(eDirection == SDRTEXTANI_UP || eDirection == SDRTEXTANI_DOWN)
401             {
402                 bRet = sal_False;
403             }
404         }
405     }
406     return bRet;
407 }
408 
IsAutoGrowWidth() const409 FASTBOOL SdrTextObj::IsAutoGrowWidth() const
410 {
411     if(!bTextFrame)
412         return sal_False; // AutoGrow nur bei TextFrames
413 
414     const SfxItemSet& rSet = GetObjectItemSet();
415     sal_Bool bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue();
416 
417     // #101684#
418     sal_Bool bInEditMOde = IsInEditMode();
419 
420     if(!bInEditMOde && bRet)
421     {
422         SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
423 
424         if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
425         {
426             SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
427 
428             if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
429             {
430                 bRet = sal_False;
431             }
432         }
433     }
434     return bRet;
435 }
436 
GetTextHorizontalAdjust() const437 SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust() const
438 {
439     return GetTextHorizontalAdjust(GetObjectItemSet());
440 }
441 
GetTextHorizontalAdjust(const SfxItemSet & rSet) const442 SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust(const SfxItemSet& rSet) const
443 {
444     if(IsContourTextFrame())
445         return SDRTEXTHORZADJUST_BLOCK;
446 
447     SdrTextHorzAdjust eRet = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
448 
449     // #101684#
450     sal_Bool bInEditMode = IsInEditMode();
451 
452     if(!bInEditMode && eRet == SDRTEXTHORZADJUST_BLOCK)
453     {
454         SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
455 
456         if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
457         {
458             SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
459 
460             if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
461             {
462                 eRet = SDRTEXTHORZADJUST_LEFT;
463             }
464         }
465     }
466 
467     return eRet;
468 } // defaults: BLOCK fuer Textrahmen, CENTER fuer beschriftete Grafikobjekte
469 
GetTextVerticalAdjust() const470 SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust() const
471 {
472     return GetTextVerticalAdjust(GetObjectItemSet());
473 }
474 
GetTextVerticalAdjust(const SfxItemSet & rSet) const475 SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust(const SfxItemSet& rSet) const
476 {
477     if(IsContourTextFrame())
478         return SDRTEXTVERTADJUST_TOP;
479 
480     // #103516# Take care for vertical text animation here
481     SdrTextVertAdjust eRet = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
482     sal_Bool bInEditMode = IsInEditMode();
483 
484     // #103516# Take care for vertical text animation here
485     if(!bInEditMode && eRet == SDRTEXTVERTADJUST_BLOCK)
486     {
487         SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
488 
489         if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
490         {
491             SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
492 
493             if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
494             {
495                 eRet = SDRTEXTVERTADJUST_TOP;
496             }
497         }
498     }
499 
500     return eRet;
501 } // defaults: TOP fuer Textrahmen, CENTER fuer beschriftete Grafikobjekte
502 
ImpJustifyRect(Rectangle & rRect) const503 void SdrTextObj::ImpJustifyRect(Rectangle& rRect) const
504 {
505     if (!rRect.IsEmpty()) {
506         rRect.Justify();
507         if (rRect.Left()==rRect.Right()) rRect.Right()++;
508         if (rRect.Top()==rRect.Bottom()) rRect.Bottom()++;
509     }
510 }
511 
ImpCheckShear()512 void SdrTextObj::ImpCheckShear()
513 {
514     if (bNoShear && aGeo.nShearWink!=0) {
515         aGeo.nShearWink=0;
516         aGeo.nTan=0;
517     }
518 }
519 
TakeObjInfo(SdrObjTransformInfoRec & rInfo) const520 void SdrTextObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
521 {
522     FASTBOOL bNoTextFrame=!IsTextFrame();
523     rInfo.bResizeFreeAllowed=bNoTextFrame || aGeo.nDrehWink%9000==0;
524     rInfo.bResizePropAllowed=sal_True;
525     rInfo.bRotateFreeAllowed=sal_True;
526     rInfo.bRotate90Allowed  =sal_True;
527     rInfo.bMirrorFreeAllowed=bNoTextFrame;
528     rInfo.bMirror45Allowed  =bNoTextFrame;
529     rInfo.bMirror90Allowed  =bNoTextFrame;
530 
531     // allow transparence
532     rInfo.bTransparenceAllowed = sal_True;
533 
534     // gradient depends on fillstyle
535     XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
536     rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
537     rInfo.bShearAllowed     =bNoTextFrame;
538     rInfo.bEdgeRadiusAllowed=sal_True;
539     FASTBOOL bCanConv=ImpCanConvTextToCurve();
540     rInfo.bCanConvToPath    =bCanConv;
541     rInfo.bCanConvToPoly    =bCanConv;
542     rInfo.bCanConvToPathLineToArea=bCanConv;
543     rInfo.bCanConvToPolyLineToArea=bCanConv;
544     rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
545 }
546 
GetObjIdentifier() const547 sal_uInt16 SdrTextObj::GetObjIdentifier() const
548 {
549     return sal_uInt16(eTextKind);
550 }
551 
HasTextImpl(SdrOutliner * pOutliner)552 bool SdrTextObj::HasTextImpl( SdrOutliner* pOutliner )
553 {
554     bool bRet=false;
555     if(pOutliner)
556     {
557         Paragraph* p1stPara=pOutliner->GetParagraph( 0 );
558         sal_uIntPtr nParaAnz=pOutliner->GetParagraphCount();
559         if(p1stPara==NULL)
560             nParaAnz=0;
561 
562         if(nParaAnz==1)
563         {
564             // if it is only one paragraph, check if that paragraph is empty
565             XubString aStr(pOutliner->GetText(p1stPara));
566 
567             if(!aStr.Len())
568                 nParaAnz = 0;
569         }
570 
571         bRet= nParaAnz!=0;
572     }
573     return bRet;
574 }
575 
HasEditText() const576 FASTBOOL SdrTextObj::HasEditText() const
577 {
578     return HasTextImpl( pEdtOutl );
579 }
580 
SetPage(SdrPage * pNewPage)581 void SdrTextObj::SetPage(SdrPage* pNewPage)
582 {
583     FASTBOOL bRemove=pNewPage==NULL && pPage!=NULL;
584     FASTBOOL bInsert=pNewPage!=NULL && pPage==NULL;
585     FASTBOOL bLinked=IsLinkedText();
586 
587     if (bLinked && bRemove) {
588         ImpLinkAbmeldung();
589     }
590 
591     SdrAttrObj::SetPage(pNewPage);
592 
593     if (bLinked && bInsert) {
594         ImpLinkAnmeldung();
595     }
596 }
597 
SetModel(SdrModel * pNewModel)598 void SdrTextObj::SetModel(SdrModel* pNewModel)
599 {
600     SdrModel* pOldModel=pModel;
601     bool bLinked=IsLinkedText();
602     bool bChg=pNewModel!=pModel;
603 
604     if (bLinked && bChg)
605     {
606         ImpLinkAbmeldung();
607     }
608 
609     SdrAttrObj::SetModel(pNewModel);
610 
611     if( bChg )
612     {
613         if( pNewModel != 0 && pOldModel != 0 )
614             SetTextSizeDirty();
615 
616         sal_Int32 nCount = getTextCount();
617         for( sal_Int32 nText = 0; nText < nCount; nText++ )
618         {
619             SdrText* pText = getText( nText );
620             if( pText )
621                 pText->SetModel( pNewModel );
622         }
623     }
624 
625     if (bLinked && bChg)
626     {
627         ImpLinkAnmeldung();
628     }
629 }
630 
NbcSetEckenradius(long nRad)631 FASTBOOL SdrTextObj::NbcSetEckenradius(long nRad)
632 {
633     SetObjectItem(SdrEckenradiusItem(nRad));
634     return sal_True;
635 }
636 
NbcSetAutoGrowHeight(bool bAuto)637 FASTBOOL SdrTextObj::NbcSetAutoGrowHeight(bool bAuto)
638 {
639     if(bTextFrame)
640     {
641         SetObjectItem(SdrTextAutoGrowHeightItem(bAuto));
642         return sal_True;
643     }
644     return sal_False;
645 }
646 
647 // #115391# This implementation is based on the object size (aRect) and the
648 // states of IsAutoGrowWidth/Height to correctly set TextMinFrameWidth/Height
AdaptTextMinSize()649 void SdrTextObj::AdaptTextMinSize()
650 {
651     if(bTextFrame && (!pModel || !pModel->IsPasteResize()))
652     {
653         const bool bW(IsAutoGrowWidth());
654         const bool bH(IsAutoGrowHeight());
655 
656         if(bW || bH)
657         {
658             SfxItemSet aSet(
659                 *GetObjectItemSet().GetPool(),
660                 SDRATTR_TEXT_MINFRAMEHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
661                 SDRATTR_TEXT_MINFRAMEWIDTH, SDRATTR_TEXT_AUTOGROWWIDTH, // contains SDRATTR_TEXT_MAXFRAMEWIDTH
662                 0, 0);
663 
664             if(bW)
665             {
666                 const long nDist(GetTextLeftDistance() + GetTextRightDistance());
667                 const long nW(std::max(long(0), (long)(aRect.GetWidth() - 1 - nDist)));
668 
669                 aSet.Put(SdrTextMinFrameWidthItem(nW));
670 
671                 if(!IsVerticalWriting() && bDisableAutoWidthOnDragging)
672                 {
673                     bDisableAutoWidthOnDragging = true;
674                     aSet.Put(SdrTextAutoGrowWidthItem(false));
675                 }
676             }
677 
678             if(bH)
679             {
680                 const long nDist(GetTextUpperDistance() + GetTextLowerDistance());
681                 const long nH(std::max(long(0), (long)(aRect.GetHeight() - 1 - nDist)));
682 
683                 aSet.Put(SdrTextMinFrameHeightItem(nH));
684 
685                 if(IsVerticalWriting() && bDisableAutoWidthOnDragging)
686                 {
687                     bDisableAutoWidthOnDragging = false;
688                     aSet.Put(SdrTextAutoGrowHeightItem(false));
689                 }
690             }
691 
692             SetObjectItemSet(aSet);
693             NbcAdjustTextFrameWidthAndHeight();
694         }
695     }
696 }
697 
NbcSetMaxTextFrameHeight(long nHgt)698 FASTBOOL SdrTextObj::NbcSetMaxTextFrameHeight(long nHgt)
699 {
700     if(bTextFrame)
701     {
702         SetObjectItem(SdrTextMaxFrameHeightItem(nHgt));
703         return sal_True;
704     }
705     return sal_False;
706 }
707 
NbcSetAutoGrowWidth(bool bAuto)708 FASTBOOL SdrTextObj::NbcSetAutoGrowWidth(bool bAuto)
709 {
710     if(bTextFrame)
711     {
712         SetObjectItem(SdrTextAutoGrowWidthItem(bAuto));
713         return sal_True;
714     }
715     return sal_False;
716 }
717 
NbcSetMaxTextFrameWidth(long nWdt)718 FASTBOOL SdrTextObj::NbcSetMaxTextFrameWidth(long nWdt)
719 {
720     if(bTextFrame)
721     {
722         SetObjectItem(SdrTextMaxFrameWidthItem(nWdt));
723         return sal_True;
724     }
725     return sal_False;
726 }
727 
NbcSetFitToSize(SdrFitToSizeType eFit)728 FASTBOOL SdrTextObj::NbcSetFitToSize(SdrFitToSizeType eFit)
729 {
730     if(bTextFrame)
731     {
732         SetObjectItem(SdrTextFitToSizeTypeItem(eFit));
733         return sal_True;
734     }
735     return sal_False;
736 }
737 
ImpSetContourPolygon(SdrOutliner & rOutliner,Rectangle & rAnchorRect,sal_Bool bLineWidth) const738 void SdrTextObj::ImpSetContourPolygon( SdrOutliner& rOutliner, Rectangle& rAnchorRect, sal_Bool bLineWidth ) const
739 {
740     basegfx::B2DPolyPolygon aXorPolyPolygon(TakeXorPoly());
741     basegfx::B2DPolyPolygon* pContourPolyPolygon = 0L;
742     basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
743         -rAnchorRect.Left(), -rAnchorRect.Top()));
744 
745     if(aGeo.nDrehWink)
746     {
747         // Unrotate!
748         aMatrix.rotate(-aGeo.nDrehWink * nPi180);
749     }
750 
751     aXorPolyPolygon.transform(aMatrix);
752 
753     if( bLineWidth )
754     {
755         // Strichstaerke beruecksichtigen
756         // Beim Hittest muss das unterbleiben (Performance!)
757         pContourPolyPolygon = new basegfx::B2DPolyPolygon();
758 
759         // #86258# test if shadow needs to be avoided for TakeContour()
760         const SfxItemSet& rSet = GetObjectItemSet();
761         sal_Bool bShadowOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
762 
763         // #i33696#
764         // Remember TextObject currently set at the DrawOutliner, it WILL be
765         // replaced during calculating the outline since it uses an own paint
766         // and that one uses the DrawOutliner, too.
767         const SdrTextObj* pLastTextObject = rOutliner.GetTextObj();
768 
769         if(bShadowOn)
770         {
771             // #86258# force shadow off
772             SdrObject* pCopy = Clone();
773             pCopy->SetMergedItem(SdrShadowItem(sal_False));
774             *pContourPolyPolygon = pCopy->TakeContour();
775             SdrObject::Free( pCopy );
776         }
777         else
778         {
779             *pContourPolyPolygon = TakeContour();
780         }
781 
782         // #i33696#
783         // restore remembered text object
784         if(pLastTextObject != rOutliner.GetTextObj())
785         {
786             rOutliner.SetTextObj(pLastTextObject);
787         }
788 
789         pContourPolyPolygon->transform(aMatrix);
790     }
791 
792     rOutliner.SetPolygon(aXorPolyPolygon, pContourPolyPolygon);
793 }
794 
TakeUnrotatedSnapRect(Rectangle & rRect) const795 void SdrTextObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
796 {
797     rRect=aRect;
798 }
799 
TakeTextAnchorRect(Rectangle & rAnchorRect) const800 void SdrTextObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
801 {
802     long nLeftDist=GetTextLeftDistance();
803     long nRightDist=GetTextRightDistance();
804     long nUpperDist=GetTextUpperDistance();
805     long nLowerDist=GetTextLowerDistance();
806     Rectangle aAnkRect(aRect); // Rect innerhalb dem geankert wird
807     FASTBOOL bFrame=IsTextFrame();
808     if (!bFrame) {
809         TakeUnrotatedSnapRect(aAnkRect);
810     }
811     Point aRotateRef(aAnkRect.TopLeft());
812     aAnkRect.Left()+=nLeftDist;
813     aAnkRect.Top()+=nUpperDist;
814     aAnkRect.Right()-=nRightDist;
815     aAnkRect.Bottom()-=nLowerDist;
816 
817     // #108816#
818     // Since sizes may be bigger than the object bounds it is necessary to
819     // justify the rect now.
820     ImpJustifyRect(aAnkRect);
821 
822     if (bFrame) {
823         // !!! hier noch etwas verfeinern !!!
824         if (aAnkRect.GetWidth()<2) aAnkRect.Right()=aAnkRect.Left()+1;   // Mindestgroesse 2
825         if (aAnkRect.GetHeight()<2) aAnkRect.Bottom()=aAnkRect.Top()+1;  // Mindestgroesse 2
826     }
827     if (aGeo.nDrehWink!=0) {
828         Point aTmpPt(aAnkRect.TopLeft());
829         RotatePoint(aTmpPt,aRotateRef,aGeo.nSin,aGeo.nCos);
830         aTmpPt-=aAnkRect.TopLeft();
831         aAnkRect.Move(aTmpPt.X(),aTmpPt.Y());
832     }
833     rAnchorRect=aAnkRect;
834 }
835 
TakeTextRect(SdrOutliner & rOutliner,Rectangle & rTextRect,FASTBOOL bNoEditText,Rectangle * pAnchorRect,sal_Bool bLineWidth) const836 void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
837                                Rectangle* pAnchorRect, sal_Bool bLineWidth ) const
838 {
839     Rectangle aAnkRect; // Rect innerhalb dem geankert wird
840     TakeTextAnchorRect(aAnkRect);
841     SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
842     SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
843     SdrTextAniKind      eAniKind=GetTextAniKind();
844     SdrTextAniDirection eAniDirection=GetTextAniDirection();
845 
846     SdrFitToSizeType eFit=GetFitToSize();
847     FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
848     FASTBOOL bContourFrame=IsContourTextFrame();
849 
850     FASTBOOL bFrame=IsTextFrame();
851     sal_uIntPtr nStat0=rOutliner.GetControlWord();
852     Size aNullSize;
853     if (!bContourFrame)
854     {
855         rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
856         rOutliner.SetMinAutoPaperSize(aNullSize);
857         rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
858     }
859 
860     if (!bFitToSize && !bContourFrame)
861     {
862         long nAnkWdt=aAnkRect.GetWidth();
863         long nAnkHgt=aAnkRect.GetHeight();
864         if (bFrame)
865         {
866             long nWdt=nAnkWdt;
867             long nHgt=nAnkHgt;
868 
869             // #101684#
870             sal_Bool bInEditMode = IsInEditMode();
871 
872             if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
873             {
874                 // Grenzenlose Papiergroesse fuer Laufschrift
875                 if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nWdt=1000000;
876                 if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nHgt=1000000;
877             }
878 
879             // #119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
880             if(IsVerticalWriting())
881             {
882                 nWdt = 1000000;
883             }
884             else
885             {
886                 nHgt = 1000000;
887             }
888 
889             rOutliner.SetMaxAutoPaperSize(Size(nWdt,nHgt));
890         }
891 
892         // #103516# New try with _BLOCK for hor and ver after completely
893         // supporting full width for vertical text.
894         if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
895         {
896             rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
897         }
898 
899         if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
900         {
901             rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
902         }
903     }
904 
905     rOutliner.SetPaperSize(aNullSize);
906     if (bContourFrame)
907         ImpSetContourPolygon( rOutliner, aAnkRect, bLineWidth );
908 
909     // put text into the outliner, if available from the edit outliner
910     SdrText* pText = getActiveText();
911     OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
912     OutlinerParaObject* pPara = (pEdtOutl && !bNoEditText) ? pEdtOutl->CreateParaObject() : pOutlinerParaObject;
913 
914     if (pPara)
915     {
916         sal_Bool bHitTest = sal_False;
917         if( pModel )
918             bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
919 
920         const SdrTextObj* pTestObj = rOutliner.GetTextObj();
921         if( !pTestObj || !bHitTest || pTestObj != this ||
922             pTestObj->GetOutlinerParaObject() != pOutlinerParaObject )
923         {
924             if( bHitTest ) // #i33696# take back fix #i27510#
925             {
926                 rOutliner.SetTextObj( this );
927                 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
928             }
929 
930             rOutliner.SetUpdateMode(sal_True);
931             rOutliner.SetText(*pPara);
932         }
933     }
934     else
935     {
936         rOutliner.SetTextObj( NULL );
937     }
938 
939     if (pEdtOutl && !bNoEditText && pPara)
940         delete pPara;
941 
942     rOutliner.SetUpdateMode(sal_True);
943     rOutliner.SetControlWord(nStat0);
944 
945     if( pText )
946         pText->CheckPortionInfo(rOutliner);
947 
948     Point aTextPos(aAnkRect.TopLeft());
949     Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder?
950 
951     // #106653#
952     // For draw objects containing text correct hor/ver alignment if text is bigger
953     // than the object itself. Without that correction, the text would always be
954     // formatted to the left edge (or top edge when vertical) of the draw object.
955     if(!IsTextFrame())
956     {
957         if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
958         {
959             // #110129#
960             // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
961             // else the alignment is wanted.
962             if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
963             {
964                 eHAdj = SDRTEXTHORZADJUST_CENTER;
965             }
966         }
967 
968         if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
969         {
970             // #110129#
971             // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
972             // else the alignment is wanted.
973             if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
974             {
975                 eVAdj = SDRTEXTVERTADJUST_CENTER;
976             }
977         }
978     }
979 
980     if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
981     {
982         long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
983         if (eHAdj==SDRTEXTHORZADJUST_CENTER)
984             aTextPos.X()+=nFreeWdt/2;
985         if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
986             aTextPos.X()+=nFreeWdt;
987     }
988     if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
989     {
990         long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
991         if (eVAdj==SDRTEXTVERTADJUST_CENTER)
992             aTextPos.Y()+=nFreeHgt/2;
993         if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
994             aTextPos.Y()+=nFreeHgt;
995     }
996     if (aGeo.nDrehWink!=0)
997         RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
998 
999     if (pAnchorRect)
1000         *pAnchorRect=aAnkRect;
1001 
1002     // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt
1003     rTextRect=Rectangle(aTextPos,aTextSiz);
1004     if (bContourFrame)
1005         rTextRect=aAnkRect;
1006 }
1007 
GetEditOutlinerParaObject() const1008 OutlinerParaObject* SdrTextObj::GetEditOutlinerParaObject() const
1009 {
1010     OutlinerParaObject* pPara=NULL;
1011     if( HasTextImpl( pEdtOutl ) )
1012     {
1013         sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( pEdtOutl->GetParagraphCount() );
1014         pPara = pEdtOutl->CreateParaObject(0, nParaAnz);
1015     }
1016     return pPara;
1017 }
1018 
ImpSetCharStretching(SdrOutliner & rOutliner,const Rectangle & rTextRect,const Rectangle & rAnchorRect,Fraction & rFitXKorreg) const1019 void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Rectangle& rTextRect, const Rectangle& rAnchorRect, Fraction& rFitXKorreg) const
1020 {
1021     OutputDevice* pOut = rOutliner.GetRefDevice();
1022     sal_Bool bNoStretching(sal_False);
1023 
1024     if(pOut && pOut->GetOutDevType() == OUTDEV_PRINTER)
1025     {
1026         // #35762#: Checken ob CharStretching ueberhaupt moeglich
1027         GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
1028         UniString aTestString(sal_Unicode('J'));
1029 
1030         if(pMtf && (!pMtf->IsRecord() || pMtf->IsPause()))
1031             pMtf = NULL;
1032 
1033         if(pMtf)
1034             pMtf->Pause(sal_True);
1035 
1036         Font aFontMerk(pOut->GetFont());
1037         Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ) );
1038 
1039         aTmpFont.SetSize(Size(0,100));
1040         pOut->SetFont(aTmpFont);
1041         Size aSize1(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
1042         aTmpFont.SetSize(Size(800,100));
1043         pOut->SetFont(aTmpFont);
1044         Size aSize2(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
1045         pOut->SetFont(aFontMerk);
1046 
1047         if(pMtf)
1048             pMtf->Pause(sal_False);
1049 
1050         bNoStretching = (aSize1 == aSize2);
1051 
1052 #ifdef WNT
1053         // #35762# Windows vergroessert bei Size(100,500) den Font proportional
1054         // Und das finden wir nicht so schoen.
1055         if(aSize2.Height() >= aSize1.Height() * 2)
1056         {
1057             bNoStretching = sal_True;
1058         }
1059 #endif
1060     }
1061     unsigned nLoopCount=0;
1062     FASTBOOL bNoMoreLoop=sal_False;
1063     long nXDiff0=0x7FFFFFFF;
1064     long nWantWdt=rAnchorRect.Right()-rAnchorRect.Left();
1065     long nIsWdt=rTextRect.Right()-rTextRect.Left();
1066     if (nIsWdt==0) nIsWdt=1;
1067 
1068     long nWantHgt=rAnchorRect.Bottom()-rAnchorRect.Top();
1069     long nIsHgt=rTextRect.Bottom()-rTextRect.Top();
1070     if (nIsHgt==0) nIsHgt=1;
1071 
1072     long nXTolPl=nWantWdt/100; // Toleranz +1%
1073     long nXTolMi=nWantWdt/25;  // Toleranz -4%
1074     long nXKorr =nWantWdt/20;  // Korrekturmasstab 5%
1075 
1076     long nX=(nWantWdt*100) /nIsWdt; // X-Stretching berechnen
1077     long nY=(nWantHgt*100) /nIsHgt; // Y-Stretching berechnen
1078     FASTBOOL bChkX=sal_True;
1079     FASTBOOL bChkY=sal_True;
1080     if (bNoStretching) { // #35762# evtl. nur proportional moeglich
1081         if (nX>nY) { nX=nY; bChkX=sal_False; }
1082         else { nY=nX; bChkY=sal_False; }
1083     }
1084 
1085     while (nLoopCount<5 && !bNoMoreLoop) {
1086         if (nX<0) nX=-nX;
1087         if (nX<1) { nX=1; bNoMoreLoop=sal_True; }
1088         if (nX>65535) { nX=65535; bNoMoreLoop=sal_True; }
1089 
1090         if (nY<0) nY=-nY;
1091         if (nY<1) { nY=1; bNoMoreLoop=sal_True; }
1092         if (nY>65535) { nY=65535; bNoMoreLoop=sal_True; }
1093 
1094         // exception, there is no text yet (horizontal case)
1095         if(nIsWdt <= 1)
1096         {
1097             nX = nY;
1098             bNoMoreLoop = sal_True;
1099         }
1100 
1101         // #87877# exception, there is no text yet (vertical case)
1102         if(nIsHgt <= 1)
1103         {
1104             nY = nX;
1105             bNoMoreLoop = sal_True;
1106         }
1107 
1108         rOutliner.SetGlobalCharStretching((sal_uInt16)nX,(sal_uInt16)nY);
1109         nLoopCount++;
1110         Size aSiz(rOutliner.CalcTextSize());
1111         long nXDiff=aSiz.Width()-nWantWdt;
1112         rFitXKorreg=Fraction(nWantWdt,aSiz.Width());
1113         if (((nXDiff>=nXTolMi || !bChkX) && nXDiff<=nXTolPl) || nXDiff==nXDiff0/*&& Abs(nYDiff)<=nYTol*/) {
1114             bNoMoreLoop=sal_True;
1115         } else {
1116             // Stretchingfaktoren korregieren
1117             long nMul=nWantWdt;
1118             long nDiv=aSiz.Width();
1119             if (Abs(nXDiff)<=2*nXKorr) {
1120                 if (nMul>nDiv) nDiv+=(nMul-nDiv)/2; // und zwar nur um die haelfte des berechneten
1121                 else nMul+=(nDiv-nMul)/2;           // weil die EE ja eh wieder falsch rechnet
1122             }
1123             nX=nX*nMul/nDiv;
1124             if (bNoStretching) nY=nX;
1125         }
1126         nXDiff0=nXDiff;
1127     }
1128 }
1129 
StartTextAnimation(OutputDevice *,const Point &,long)1130 void SdrTextObj::StartTextAnimation(OutputDevice* /*pOutDev*/, const Point& /*rOffset*/, long /*nExtraData*/)
1131 {
1132     // #111096#
1133     // use new text animation
1134     SetTextAnimationAllowed(sal_True);
1135 }
1136 
StopTextAnimation(OutputDevice *,long)1137 void SdrTextObj::StopTextAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
1138 {
1139     // #111096#
1140     // use new text animation
1141     SetTextAnimationAllowed(sal_False);
1142 }
1143 
TakeObjNameSingul(XubString & rName) const1144 void SdrTextObj::TakeObjNameSingul(XubString& rName) const
1145 {
1146     XubString aStr;
1147 
1148     switch(eTextKind)
1149     {
1150         case OBJ_OUTLINETEXT:
1151         {
1152             aStr = ImpGetResStr(STR_ObjNameSingulOUTLINETEXT);
1153             break;
1154         }
1155 
1156         case OBJ_TITLETEXT  :
1157         {
1158             aStr = ImpGetResStr(STR_ObjNameSingulTITLETEXT);
1159             break;
1160         }
1161 
1162         default:
1163         {
1164             if(IsLinkedText())
1165                 aStr = ImpGetResStr(STR_ObjNameSingulTEXTLNK);
1166             else
1167                 aStr = ImpGetResStr(STR_ObjNameSingulTEXT);
1168             break;
1169         }
1170     }
1171 
1172     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1173     if(pOutlinerParaObject && eTextKind != OBJ_OUTLINETEXT)
1174     {
1175         // Macht bei OUTLINETEXT wohl derzeit noch etwas Probleme
1176         XubString aStr2(pOutlinerParaObject->GetTextObject().GetText(0));
1177         aStr2.EraseLeadingChars();
1178 
1179         // #69446# avoid non expanded text portions in object name
1180         // (second condition is new)
1181         if(aStr2.Len() && aStr2.Search(sal_Unicode(255)) == STRING_NOTFOUND)
1182         {
1183             // #76681# space between ResStr and content text
1184             aStr += sal_Unicode(' ');
1185 
1186             aStr += sal_Unicode('\'');
1187 
1188             if(aStr2.Len() > 10)
1189             {
1190                 aStr2.Erase(8);
1191                 aStr2.AppendAscii("...", 3);
1192             }
1193 
1194             aStr += aStr2;
1195             aStr += sal_Unicode('\'');
1196         }
1197     }
1198 
1199     rName = aStr;
1200 
1201     String aName( GetName() );
1202     if(aName.Len())
1203     {
1204         rName += sal_Unicode(' ');
1205         rName += sal_Unicode('\'');
1206         rName += aName;
1207         rName += sal_Unicode('\'');
1208     }
1209 
1210 }
1211 
TakeObjNamePlural(XubString & rName) const1212 void SdrTextObj::TakeObjNamePlural(XubString& rName) const
1213 {
1214     switch (eTextKind) {
1215         case OBJ_OUTLINETEXT: rName=ImpGetResStr(STR_ObjNamePluralOUTLINETEXT); break;
1216         case OBJ_TITLETEXT  : rName=ImpGetResStr(STR_ObjNamePluralTITLETEXT);   break;
1217         default: {
1218             if (IsLinkedText()) {
1219                 rName=ImpGetResStr(STR_ObjNamePluralTEXTLNK);
1220             } else {
1221                 rName=ImpGetResStr(STR_ObjNamePluralTEXT);
1222             }
1223         } break;
1224     } // switch
1225 }
1226 
operator =(const SdrObject & rObj)1227 void SdrTextObj::operator=(const SdrObject& rObj)
1228 {
1229     // call parent
1230     SdrObject::operator=(rObj);
1231 
1232     const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >( &rObj );
1233     if (pTextObj!=NULL)
1234     {
1235         aRect     =pTextObj->aRect;
1236         aGeo      =pTextObj->aGeo;
1237         eTextKind =pTextObj->eTextKind;
1238         bTextFrame=pTextObj->bTextFrame;
1239         aTextSize=pTextObj->aTextSize;
1240         bTextSizeDirty=pTextObj->bTextSizeDirty;
1241 
1242         // #101776# Not all of the necessary parameters were copied yet.
1243         bNoShear = pTextObj->bNoShear;
1244         bNoRotate = pTextObj->bNoRotate;
1245         bNoMirror = pTextObj->bNoMirror;
1246         bDisableAutoWidthOnDragging = pTextObj->bDisableAutoWidthOnDragging;
1247 
1248         OutlinerParaObject* pNewOutlinerParaObject = 0;
1249 
1250         SdrText* pText = getActiveText();
1251 
1252         if( pText && pTextObj->HasText() )
1253         {
1254             const Outliner* pEO=pTextObj->pEdtOutl;
1255             if (pEO!=NULL)
1256             {
1257                 pNewOutlinerParaObject = pEO->CreateParaObject();
1258             }
1259             else
1260             {
1261                 pNewOutlinerParaObject = new OutlinerParaObject(*pTextObj->getActiveText()->GetOutlinerParaObject());
1262             }
1263         }
1264 
1265         mpText->SetOutlinerParaObject( pNewOutlinerParaObject );
1266         ImpSetTextStyleSheetListeners();
1267     }
1268 }
1269 
TakeXorPoly() const1270 basegfx::B2DPolyPolygon SdrTextObj::TakeXorPoly() const
1271 {
1272     Polygon aPol(aRect);
1273     if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1274     if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1275 
1276     basegfx::B2DPolyPolygon aRetval;
1277     aRetval.append(aPol.getB2DPolygon());
1278     return aRetval;
1279 }
1280 
TakeContour() const1281 basegfx::B2DPolyPolygon SdrTextObj::TakeContour() const
1282 {
1283     basegfx::B2DPolyPolygon aRetval(SdrAttrObj::TakeContour());
1284 
1285     // und nun noch ggf. das BoundRect des Textes dazu
1286     if ( pModel && GetOutlinerParaObject() && !IsFontwork() && !IsContourTextFrame() )
1287     {
1288         // #80328# using Clone()-Paint() strategy inside TakeContour() leaves a destroyed
1289         // SdrObject as pointer in DrawOutliner. Set *this again in fetching the outliner
1290         // in every case
1291         SdrOutliner& rOutliner=ImpGetDrawOutliner();
1292 
1293         Rectangle aAnchor2;
1294         Rectangle aR;
1295         TakeTextRect(rOutliner,aR,sal_False,&aAnchor2);
1296         rOutliner.Clear();
1297         SdrFitToSizeType eFit=GetFitToSize();
1298         FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
1299         if (bFitToSize) aR=aAnchor2;
1300         Polygon aPol(aR);
1301         if (aGeo.nDrehWink!=0) RotatePoly(aPol,aR.TopLeft(),aGeo.nSin,aGeo.nCos);
1302 
1303         aRetval.append(aPol.getB2DPolygon());
1304     }
1305 
1306     return aRetval;
1307 }
1308 
RecalcSnapRect()1309 void SdrTextObj::RecalcSnapRect()
1310 {
1311     if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) {
1312         Polygon aPol(aRect);
1313         if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1314         if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1315         maSnapRect=aPol.GetBoundRect();
1316     } else {
1317         maSnapRect=aRect;
1318     }
1319 }
1320 
GetSnapPointCount() const1321 sal_uInt32 SdrTextObj::GetSnapPointCount() const
1322 {
1323     return 4L;
1324 }
1325 
GetSnapPoint(sal_uInt32 i) const1326 Point SdrTextObj::GetSnapPoint(sal_uInt32 i) const
1327 {
1328     Point aP;
1329     switch (i) {
1330         case 0: aP=aRect.TopLeft(); break;
1331         case 1: aP=aRect.TopRight(); break;
1332         case 2: aP=aRect.BottomLeft(); break;
1333         case 3: aP=aRect.BottomRight(); break;
1334         default: aP=aRect.Center(); break;
1335     }
1336     if (aGeo.nShearWink!=0) ShearPoint(aP,aRect.TopLeft(),aGeo.nTan);
1337     if (aGeo.nDrehWink!=0) RotatePoint(aP,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1338     return aP;
1339 }
1340 
ImpCheckMasterCachable()1341 void SdrTextObj::ImpCheckMasterCachable()
1342 {
1343     bNotMasterCachable=sal_False;
1344 
1345     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1346 
1347     if(!bNotVisibleAsMaster && pOutlinerParaObject && pOutlinerParaObject->IsEditDoc() )
1348     {
1349         const EditTextObject& rText= pOutlinerParaObject->GetTextObject();
1350         bNotMasterCachable=rText.HasField(SvxPageField::StaticType());
1351         if( !bNotMasterCachable )
1352         {
1353             bNotMasterCachable=rText.HasField(SvxHeaderField::StaticType());
1354             if( !bNotMasterCachable )
1355             {
1356                 bNotMasterCachable=rText.HasField(SvxFooterField::StaticType());
1357                 if( !bNotMasterCachable )
1358                 {
1359                     bNotMasterCachable=rText.HasField(SvxDateTimeField::StaticType());
1360                 }
1361             }
1362         }
1363     }
1364 }
1365 
1366 // #101029#: Extracted from ImpGetDrawOutliner()
ImpInitDrawOutliner(SdrOutliner & rOutl) const1367 void SdrTextObj::ImpInitDrawOutliner( SdrOutliner& rOutl ) const
1368 {
1369     rOutl.SetUpdateMode(sal_False);
1370     sal_uInt16 nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
1371     if ( !IsOutlText() )
1372         nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
1373     rOutl.Init( nOutlinerMode );
1374 
1375     rOutl.SetGlobalCharStretching(100,100);
1376     sal_uIntPtr nStat=rOutl.GetControlWord();
1377     nStat&=~(EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE);
1378     rOutl.SetControlWord(nStat);
1379     Size aNullSize;
1380     Size aMaxSize(100000,100000);
1381     rOutl.SetMinAutoPaperSize(aNullSize);
1382     rOutl.SetMaxAutoPaperSize(aMaxSize);
1383     rOutl.SetPaperSize(aMaxSize);
1384     rOutl.ClearPolygon();
1385 }
1386 
ImpGetDrawOutliner() const1387 SdrOutliner& SdrTextObj::ImpGetDrawOutliner() const
1388 {
1389     SdrOutliner& rOutl=pModel->GetDrawOutliner(this);
1390 
1391     // #101029#: Code extracted to ImpInitDrawOutliner()
1392     ImpInitDrawOutliner( rOutl );
1393 
1394     return rOutl;
1395 }
1396 
CreateDrawOutliner()1397 boost::shared_ptr< SdrOutliner > SdrTextObj::CreateDrawOutliner()
1398 {
1399     boost::shared_ptr< SdrOutliner > xDrawOutliner( pModel->CreateDrawOutliner(this) );
1400     ImpInitDrawOutliner( *(xDrawOutliner.get()) );
1401     return xDrawOutliner;
1402 }
1403 
1404 // #101029#: Extracted from Paint()
ImpSetupDrawOutlinerForPaint(FASTBOOL bContourFrame,SdrOutliner & rOutliner,Rectangle & rTextRect,Rectangle & rAnchorRect,Rectangle & rPaintRect,Fraction & rFitXKorreg) const1405 void SdrTextObj::ImpSetupDrawOutlinerForPaint( FASTBOOL         bContourFrame,
1406                                                SdrOutliner&     rOutliner,
1407                                                Rectangle&       rTextRect,
1408                                                Rectangle&       rAnchorRect,
1409                                                Rectangle&       rPaintRect,
1410                                                Fraction&        rFitXKorreg ) const
1411 {
1412     if (!bContourFrame)
1413     {
1414         // FitToSize erstmal nicht mit ContourFrame
1415         SdrFitToSizeType eFit=GetFitToSize();
1416         if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
1417         {
1418             sal_uIntPtr nStat=rOutliner.GetControlWord();
1419             nStat|=EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE;
1420             rOutliner.SetControlWord(nStat);
1421         }
1422     }
1423     rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
1424     TakeTextRect(rOutliner, rTextRect, sal_False, &rAnchorRect);
1425     rPaintRect = rTextRect;
1426 
1427     if (!bContourFrame)
1428     {
1429         // FitToSize erstmal nicht mit ContourFrame
1430         SdrFitToSizeType eFit=GetFitToSize();
1431         if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
1432         {
1433             ImpSetCharStretching(rOutliner,rTextRect,rAnchorRect,rFitXKorreg);
1434             rPaintRect=rAnchorRect;
1435         }
1436     }
1437 }
1438 
SetupOutlinerFormatting(SdrOutliner & rOutl,Rectangle & rPaintRect) const1439 void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1440 {
1441     ImpInitDrawOutliner( rOutl );
1442     UpdateOutlinerFormatting( rOutl, rPaintRect );
1443 }
1444 
UpdateOutlinerFormatting(SdrOutliner & rOutl,Rectangle & rPaintRect) const1445 void SdrTextObj::UpdateOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1446 {
1447     Rectangle aTextRect;
1448     Rectangle aAnchorRect;
1449     Fraction aFitXKorreg(1,1);
1450 
1451     FASTBOOL bContourFrame=IsContourTextFrame();
1452 
1453     if( GetModel() )
1454     {
1455         MapMode aMapMode(GetModel()->GetScaleUnit(), Point(0,0),
1456                          GetModel()->GetScaleFraction(),
1457                          GetModel()->GetScaleFraction());
1458         rOutl.SetRefMapMode(aMapMode);
1459     }
1460 
1461     ImpSetupDrawOutlinerForPaint( bContourFrame, rOutl, aTextRect, aAnchorRect, rPaintRect, aFitXKorreg );
1462 }
1463 
1464 ////////////////////////////////////////////////////////////////////////////////////////////////////
1465 
GetOutlinerParaObject() const1466 OutlinerParaObject* SdrTextObj::GetOutlinerParaObject() const
1467 {
1468     SdrText* pText = getActiveText();
1469     if( pText )
1470         return pText->GetOutlinerParaObject();
1471     else
1472         return 0;
1473 }
1474 
HasOutlinerParaObject() const1475 bool SdrTextObj::HasOutlinerParaObject() const
1476 {
1477     SdrText* pText = getActiveText();
1478     if( pText && pText->GetOutlinerParaObject() )
1479         return true;
1480     return false;
1481 }
1482 
NbcSetOutlinerParaObject(OutlinerParaObject * pTextObject)1483 void SdrTextObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
1484 {
1485     NbcSetOutlinerParaObjectForText( pTextObject, getActiveText() );
1486 }
1487 
NbcSetOutlinerParaObjectForText(OutlinerParaObject * pTextObject,SdrText * pText)1488 void SdrTextObj::NbcSetOutlinerParaObjectForText( OutlinerParaObject* pTextObject, SdrText* pText )
1489 {
1490     if( pText )
1491         pText->SetOutlinerParaObject( pTextObject );
1492 
1493     if( pText->GetOutlinerParaObject() )
1494     {
1495         SvxWritingModeItem aWritingMode(pText->GetOutlinerParaObject()->IsVertical()
1496             ? com::sun::star::text::WritingMode_TB_RL
1497             : com::sun::star::text::WritingMode_LR_TB,
1498             SDRATTR_TEXTDIRECTION);
1499         GetProperties().SetObjectItemDirect(aWritingMode);
1500     }
1501 
1502     SetTextSizeDirty();
1503     if (IsTextFrame() && (IsAutoGrowHeight() || IsAutoGrowWidth()))
1504     { // Textrahmen anpassen!
1505         NbcAdjustTextFrameWidthAndHeight();
1506     }
1507     if (!IsTextFrame())
1508     {
1509         // Das SnapRect behaelt seine Groesse bei
1510         SetRectsDirty(sal_True);
1511     }
1512 
1513     // always invalidate BoundRect on change
1514     SetBoundRectDirty();
1515     ActionChanged();
1516 
1517     ImpSetTextStyleSheetListeners();
1518     ImpCheckMasterCachable();
1519 }
1520 
NbcReformatText()1521 void SdrTextObj::NbcReformatText()
1522 {
1523     SdrText* pText = getActiveText();
1524     if( pText && pText->GetOutlinerParaObject() )
1525     {
1526         pText->ReformatText();
1527         if (bTextFrame)
1528         {
1529             NbcAdjustTextFrameWidthAndHeight();
1530         }
1531         else
1532         {
1533             // Das SnapRect behaelt seine Groesse bei
1534             SetBoundRectDirty();
1535             SetRectsDirty(sal_True);
1536         }
1537         SetTextSizeDirty();
1538         ActionChanged();
1539         // FME, AW: i22396
1540         // Necessary here since we have no compare operator at the outliner
1541         // para object which may detect changes regarding the combination
1542         // of outliner para data and configuration (e.g., change of
1543         // formatting of text numerals)
1544         GetViewContact().flushViewObjectContacts(false);
1545     }
1546 }
1547 
ReformatText()1548 void SdrTextObj::ReformatText()
1549 {
1550     if(GetOutlinerParaObject())
1551     {
1552         Rectangle aBoundRect0;
1553         if (pUserCall!=NULL)
1554             aBoundRect0=GetLastBoundRect();
1555 
1556         // #110094#-14 SendRepaintBroadcast();
1557         NbcReformatText();
1558         SetChanged();
1559         BroadcastObjectChange();
1560         SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1561     }
1562 }
1563 
NewGeoData() const1564 SdrObjGeoData* SdrTextObj::NewGeoData() const
1565 {
1566     return new SdrTextObjGeoData;
1567 }
1568 
SaveGeoData(SdrObjGeoData & rGeo) const1569 void SdrTextObj::SaveGeoData(SdrObjGeoData& rGeo) const
1570 {
1571     SdrAttrObj::SaveGeoData(rGeo);
1572     SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1573     rTGeo.aRect  =aRect;
1574     rTGeo.aGeo   =aGeo;
1575 }
1576 
RestGeoData(const SdrObjGeoData & rGeo)1577 void SdrTextObj::RestGeoData(const SdrObjGeoData& rGeo)
1578 { // RectsDirty wird von SdrObject gerufen
1579     SdrAttrObj::RestGeoData(rGeo);
1580     SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1581     aRect  =rTGeo.aRect;
1582     aGeo   =rTGeo.aGeo;
1583     SetTextSizeDirty();
1584 }
1585 
GetFitToSize() const1586 SdrFitToSizeType SdrTextObj::GetFitToSize() const
1587 {
1588     SdrFitToSizeType eType = SDRTEXTFIT_NONE;
1589 
1590     if(!IsAutoGrowWidth())
1591         eType = ((SdrTextFitToSizeTypeItem&)(GetObjectItem(SDRATTR_TEXT_FITTOSIZE))).GetValue();
1592 
1593     return eType;
1594 }
1595 
ForceOutlinerParaObject()1596 void SdrTextObj::ForceOutlinerParaObject()
1597 {
1598     SdrText* pText = getActiveText();
1599     if( pText && (pText->GetOutlinerParaObject() == 0) )
1600     {
1601         sal_uInt16 nOutlMode = OUTLINERMODE_TEXTOBJECT;
1602         if( IsTextFrame() && eTextKind == OBJ_OUTLINETEXT )
1603             nOutlMode = OUTLINERMODE_OUTLINEOBJECT;
1604 
1605         pText->ForceOutlinerParaObject( nOutlMode );
1606     }
1607 }
1608 
IsVerticalWriting() const1609 sal_Bool SdrTextObj::IsVerticalWriting() const
1610 {
1611     // #89459#
1612     if(pEdtOutl)
1613     {
1614         return pEdtOutl->IsVertical();
1615     }
1616 
1617     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1618     if(pOutlinerParaObject)
1619     {
1620         return pOutlinerParaObject->IsVertical();
1621     }
1622 
1623     return sal_False;
1624 }
1625 
SetVerticalWriting(sal_Bool bVertical)1626 void SdrTextObj::SetVerticalWriting(sal_Bool bVertical)
1627 {
1628     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1629     if( !pOutlinerParaObject && bVertical )
1630     {
1631         // we only need to force a outliner para object if the default of
1632         // horizontal text is changed
1633         ForceOutlinerParaObject();
1634         pOutlinerParaObject = GetOutlinerParaObject();
1635     }
1636 
1637     if( pOutlinerParaObject && (pOutlinerParaObject->IsVertical() != (bool)bVertical) )
1638     {
1639         // get item settings
1640         const SfxItemSet& rSet = GetObjectItemSet();
1641         sal_Bool bAutoGrowWidth = ((SdrTextAutoGrowWidthItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH)).GetValue();
1642         sal_Bool bAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue();
1643 
1644         // #103516# Also exchange hor/ver adjust items
1645         SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
1646         SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
1647 
1648         // rescue object size
1649         Rectangle aObjectRect = GetSnapRect();
1650 
1651         // prepare ItemSet to set exchanged width and height items
1652         SfxItemSet aNewSet(*rSet.GetPool(),
1653             SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
1654             // #103516# Expanded item ranges to also support hor and ver adjust.
1655             SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
1656             SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
1657             0, 0);
1658 
1659         aNewSet.Put(rSet);
1660         aNewSet.Put(SdrTextAutoGrowWidthItem(bAutoGrowHeight));
1661         aNewSet.Put(SdrTextAutoGrowHeightItem(bAutoGrowWidth));
1662 
1663         // #103516# Exchange horz and vert adjusts
1664         switch(eVert)
1665         {
1666             case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
1667             case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
1668             case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
1669             case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
1670         }
1671         switch(eHorz)
1672         {
1673             case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
1674             case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
1675             case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
1676             case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
1677         }
1678 
1679         SetObjectItemSet(aNewSet);
1680 
1681         pOutlinerParaObject = GetOutlinerParaObject();
1682         if( pOutlinerParaObject )
1683         {
1684             // set ParaObject orientation accordingly
1685             pOutlinerParaObject->SetVertical(bVertical);
1686         }
1687 
1688         // restore object size
1689         SetSnapRect(aObjectRect);
1690     }
1691 }
1692 
1693 ////////////////////////////////////////////////////////////////////////////////////////////////////
1694 //
1695 // transformation interface for StarOfficeAPI. This implements support for
1696 // homogen 3x3 matrices containing the transformation of the SdrObject. At the
1697 // moment it contains a shearX, rotation and translation, but for setting all linear
1698 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
1699 //
1700 ////////////////////////////////////////////////////////////////////////////////////////////////////
1701 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
1702 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
TRGetBaseGeometry(basegfx::B2DHomMatrix & rMatrix,basegfx::B2DPolyPolygon &) const1703 sal_Bool SdrTextObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
1704 {
1705     // get turn and shear
1706     double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
1707     double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
1708 
1709     // get aRect, this is the unrotated snaprect
1710     Rectangle aRectangle(aRect);
1711 
1712     // fill other values
1713     basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
1714     basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
1715 
1716     // position maybe relative to anchorpos, convert
1717     if( pModel && pModel->IsWriter() )
1718     {
1719         if(GetAnchorPos().X() || GetAnchorPos().Y())
1720         {
1721             aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1722         }
1723     }
1724 
1725     // force MapUnit to 100th mm
1726     const SfxMapUnit eMapUnit(GetObjectMapUnit());
1727     if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1728     {
1729         switch(eMapUnit)
1730         {
1731             case SFX_MAPUNIT_TWIP :
1732             {
1733                 // postion
1734                 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
1735                 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
1736 
1737                 // size
1738                 aScale.setX(ImplTwipsToMM(aScale.getX()));
1739                 aScale.setY(ImplTwipsToMM(aScale.getY()));
1740 
1741                 break;
1742             }
1743             default:
1744             {
1745                 DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
1746             }
1747         }
1748     }
1749 
1750     // build matrix
1751     rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
1752         aScale,
1753         basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
1754         basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
1755         aTranslate);
1756 
1757     return sal_False;
1758 }
1759 
1760 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
1761 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
1762 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
TRSetBaseGeometry(const basegfx::B2DHomMatrix & rMatrix,const basegfx::B2DPolyPolygon &)1763 void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
1764 {
1765     // break up matrix
1766     basegfx::B2DTuple aScale;
1767     basegfx::B2DTuple aTranslate;
1768     double fRotate(0.0);
1769     double fShearX(0.0);
1770     rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1771 
1772     // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
1773     // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
1774     if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
1775     {
1776         aScale.setX(fabs(aScale.getX()));
1777         aScale.setY(fabs(aScale.getY()));
1778         fRotate = fmod(fRotate + F_PI, F_2PI);
1779     }
1780 
1781     // reset object shear and rotations
1782     aGeo.nDrehWink = 0;
1783     aGeo.RecalcSinCos();
1784     aGeo.nShearWink = 0;
1785     aGeo.RecalcTan();
1786 
1787     // force metric to pool metric
1788     const SfxMapUnit eMapUnit(GetObjectMapUnit());
1789     if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1790     {
1791         switch(eMapUnit)
1792         {
1793             case SFX_MAPUNIT_TWIP :
1794             {
1795                 // position
1796                 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
1797                 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
1798 
1799                 // size
1800                 aScale.setX(ImplMMToTwips(aScale.getX()));
1801                 aScale.setY(ImplMMToTwips(aScale.getY()));
1802 
1803                 break;
1804             }
1805             default:
1806             {
1807                 DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
1808             }
1809         }
1810     }
1811 
1812     // if anchor is used, make position relative to it
1813     if( pModel && pModel->IsWriter() )
1814     {
1815         if(GetAnchorPos().X() || GetAnchorPos().Y())
1816         {
1817             aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1818         }
1819     }
1820 
1821     // build and set BaseRect (use scale)
1822     Point aPoint = Point();
1823     Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
1824     Rectangle aBaseRect(aPoint, aSize);
1825     SetSnapRect(aBaseRect);
1826 
1827     // shear?
1828     if(!basegfx::fTools::equalZero(fShearX))
1829     {
1830         GeoStat aGeoStat;
1831         aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
1832         aGeoStat.RecalcTan();
1833         Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, sal_False);
1834     }
1835 
1836     // rotation?
1837     if(!basegfx::fTools::equalZero(fRotate))
1838     {
1839         GeoStat aGeoStat;
1840 
1841         // #i78696#
1842         // fRotate is matematically correct, but aGeoStat.nDrehWink is
1843         // mirrored -> mirror value here
1844         aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
1845         aGeoStat.RecalcSinCos();
1846         Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1847     }
1848 
1849     // translate?
1850     if(!aTranslate.equalZero())
1851     {
1852         Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
1853     }
1854 }
1855 
IsRealyEdited() const1856 bool SdrTextObj::IsRealyEdited() const
1857 {
1858     return pEdtOutl && pEdtOutl->IsModified();
1859 }
1860 
1861 /////////////////////////////////////////////////////////////////////////////////////////////////
1862 // moved inlines here form hxx
1863 
GetEckenradius() const1864 long SdrTextObj::GetEckenradius() const
1865 {
1866     return ((SdrEckenradiusItem&)(GetObjectItemSet().Get(SDRATTR_ECKENRADIUS))).GetValue();
1867 }
1868 
GetMinTextFrameHeight() const1869 long SdrTextObj::GetMinTextFrameHeight() const
1870 {
1871     return ((SdrTextMinFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEHEIGHT))).GetValue();
1872 }
1873 
GetMaxTextFrameHeight() const1874 long SdrTextObj::GetMaxTextFrameHeight() const
1875 {
1876     return ((SdrTextMaxFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEHEIGHT))).GetValue();
1877 }
1878 
GetMinTextFrameWidth() const1879 long SdrTextObj::GetMinTextFrameWidth() const
1880 {
1881     return ((SdrTextMinFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEWIDTH))).GetValue();
1882 }
1883 
GetMaxTextFrameWidth() const1884 long SdrTextObj::GetMaxTextFrameWidth() const
1885 {
1886     return ((SdrTextMaxFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEWIDTH))).GetValue();
1887 }
1888 
IsFontwork() const1889 FASTBOOL SdrTextObj::IsFontwork() const
1890 {
1891     return (bTextFrame) ? sal_False // Default ist FALSE
1892         : ((XFormTextStyleItem&)(GetObjectItemSet().Get(XATTR_FORMTXTSTYLE))).GetValue()!=XFT_NONE;
1893 }
1894 
IsHideContour() const1895 FASTBOOL SdrTextObj::IsHideContour() const
1896 {
1897     return (bTextFrame) ? sal_False // Default ist: Nein, kein HideContour; HideContour nicht bei TextFrames
1898         : ((XFormTextHideFormItem&)(GetObjectItemSet().Get(XATTR_FORMTXTHIDEFORM))).GetValue();
1899 }
1900 
IsContourTextFrame() const1901 FASTBOOL SdrTextObj::IsContourTextFrame() const
1902 {
1903     return (bTextFrame) ? sal_False // ContourFrame nicht bei normalen TextFrames
1904         : ((SdrTextContourFrameItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_CONTOURFRAME))).GetValue();
1905 }
1906 
GetTextLeftDistance() const1907 long SdrTextObj::GetTextLeftDistance() const
1908 {
1909     return ((SdrTextLeftDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LEFTDIST))).GetValue();
1910 }
1911 
GetTextRightDistance() const1912 long SdrTextObj::GetTextRightDistance() const
1913 {
1914     return ((SdrTextRightDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_RIGHTDIST))).GetValue();
1915 }
1916 
GetTextUpperDistance() const1917 long SdrTextObj::GetTextUpperDistance() const
1918 {
1919     return ((SdrTextUpperDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_UPPERDIST))).GetValue();
1920 }
1921 
GetTextLowerDistance() const1922 long SdrTextObj::GetTextLowerDistance() const
1923 {
1924     return ((SdrTextLowerDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LOWERDIST))).GetValue();
1925 }
1926 
GetTextAniKind() const1927 SdrTextAniKind SdrTextObj::GetTextAniKind() const
1928 {
1929     return ((SdrTextAniKindItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIKIND))).GetValue();
1930 }
1931 
GetTextAniDirection() const1932 SdrTextAniDirection SdrTextObj::GetTextAniDirection() const
1933 {
1934     return ((SdrTextAniDirectionItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
1935 }
1936 
1937 // #111096#
1938 // Access to thext hidden flag
GetTextHidden() const1939 sal_Bool SdrTextObj::GetTextHidden() const
1940 {
1941     return mbTextHidden;
1942 }
1943 
NbcSetTextHidden(sal_Bool bNew)1944 void SdrTextObj::NbcSetTextHidden(sal_Bool bNew)
1945 {
1946     if(bNew != mbTextHidden)
1947     {
1948         mbTextHidden = bNew;
1949     }
1950 }
1951 
1952 // #111096#
1953 // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a
1954 // painting rectangle. Rotation is excluded from the returned values.
GetTextScrollMetaFileAndRectangle(Rectangle & rScrollRectangle,Rectangle & rPaintRectangle)1955 GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle(
1956     Rectangle& rScrollRectangle, Rectangle& rPaintRectangle)
1957 {
1958     GDIMetaFile* pRetval = 0L;
1959     SdrOutliner& rOutliner = ImpGetDrawOutliner();
1960     Rectangle aTextRect;
1961     Rectangle aAnchorRect;
1962     Rectangle aPaintRect;
1963     Fraction aFitXKorreg(1,1);
1964     bool bContourFrame(IsContourTextFrame());
1965 
1966     // get outliner set up. To avoid getting a somehow rotated MetaFile,
1967     // temporarily disable object rotation.
1968     sal_Int32 nAngle(aGeo.nDrehWink);
1969     aGeo.nDrehWink = 0L;
1970     ImpSetupDrawOutlinerForPaint( bContourFrame, rOutliner, aTextRect, aAnchorRect, aPaintRect, aFitXKorreg );
1971     aGeo.nDrehWink = nAngle;
1972 
1973     Rectangle aScrollFrameRect(aPaintRect);
1974     const SfxItemSet& rSet = GetObjectItemSet();
1975     SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
1976 
1977     if(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection)
1978     {
1979         aScrollFrameRect.Left() = aAnchorRect.Left();
1980         aScrollFrameRect.Right() = aAnchorRect.Right();
1981     }
1982 
1983     if(SDRTEXTANI_UP == eDirection || SDRTEXTANI_DOWN == eDirection)
1984     {
1985         aScrollFrameRect.Top() = aAnchorRect.Top();
1986         aScrollFrameRect.Bottom() = aAnchorRect.Bottom();
1987     }
1988 
1989     // create the MetaFile
1990     pRetval = new GDIMetaFile;
1991     VirtualDevice aBlackHole;
1992     aBlackHole.EnableOutput(sal_False);
1993     pRetval->Record(&aBlackHole);
1994     Point aPaintPos = aPaintRect.TopLeft();
1995 
1996     rOutliner.Draw(&aBlackHole, aPaintPos);
1997 
1998     pRetval->Stop();
1999     pRetval->WindStart();
2000 
2001     // return PaintRectanglePixel and pRetval;
2002     rScrollRectangle = aScrollFrameRect;
2003     rPaintRectangle = aPaintRect;
2004 
2005     return pRetval;
2006 }
2007 
2008 // #111096#
2009 // Access to TextAnimationAllowed flag
IsTextAnimationAllowed() const2010 bool SdrTextObj::IsTextAnimationAllowed() const
2011 {
2012     return mbTextAnimationAllowed;
2013 }
2014 
SetTextAnimationAllowed(sal_Bool bNew)2015 void SdrTextObj::SetTextAnimationAllowed(sal_Bool bNew)
2016 {
2017     if(mbTextAnimationAllowed != bNew)
2018     {
2019         mbTextAnimationAllowed = bNew;
2020         ActionChanged();
2021     }
2022 }
2023 
2024 /** called from the SdrObjEditView during text edit when the status of the edit outliner changes */
onEditOutlinerStatusEvent(EditStatus * pEditStatus)2025 void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
2026 {
2027     const sal_uInt32 nStat = pEditStatus->GetStatusWord();
2028     const bool bGrowX=(nStat & EE_STAT_TEXTWIDTHCHANGED) !=0;
2029     const bool bGrowY=(nStat & EE_STAT_TEXTHEIGHTCHANGED) !=0;
2030     if(bTextFrame && (bGrowX || bGrowY))
2031     {
2032         const bool bAutoGrowHgt= bTextFrame && IsAutoGrowHeight();
2033         const bool bAutoGrowWdt= bTextFrame && IsAutoGrowWidth();
2034 
2035         if ((bGrowX && bAutoGrowWdt) || (bGrowY && bAutoGrowHgt))
2036         {
2037             AdjustTextFrameWidthAndHeight();
2038         }
2039     }
2040 }
2041 
2042 /** returns the currently active text. */
getActiveText() const2043 SdrText* SdrTextObj::getActiveText() const
2044 {
2045     if( !mpText )
2046         return getText( 0 );
2047     else
2048         return mpText;
2049 }
2050 
2051 /** returns the nth available text. */
getText(sal_Int32 nIndex) const2052 SdrText* SdrTextObj::getText( sal_Int32 nIndex ) const
2053 {
2054     if( nIndex == 0 )
2055     {
2056         if( mpText == 0 )
2057             const_cast< SdrTextObj* >(this)->mpText = new SdrText( *(const_cast< SdrTextObj* >(this)) );
2058         return mpText;
2059     }
2060     else
2061     {
2062         return 0;
2063     }
2064 }
2065 
2066 /** returns the number of texts available for this object. */
getTextCount() const2067 sal_Int32 SdrTextObj::getTextCount() const
2068 {
2069     return 1;
2070 }
2071 
2072 /** changes the current active text */
setActiveText(sal_Int32)2073 void SdrTextObj::setActiveText( sal_Int32 /*nIndex*/ )
2074 {
2075 }
2076 
2077 /** returns the index of the text that contains the given point or -1 */
CheckTextHit(const Point &) const2078 sal_Int32 SdrTextObj::CheckTextHit(const Point& /*rPnt*/) const
2079 {
2080     return 0;
2081 }
2082 
SetObjectItemNoBroadcast(const SfxPoolItem & rItem)2083 void SdrTextObj::SetObjectItemNoBroadcast(const SfxPoolItem& rItem)
2084 {
2085     static_cast< sdr::properties::TextProperties& >(GetProperties()).SetObjectItemNoBroadcast(rItem);
2086 }
2087 
2088 /////////////////////////////////////////////////////////////////////////////////////////////////
2089 //
2090 // Konzept des TextObjekts:
2091 // ~~~~~~~~~~~~~~~~~~~~~~~~
2092 // Attribute/Varianten:
2093 // - sal_Bool Textrahmen / beschriftetes Zeichenobjekt
2094 // - sal_Bool FontWork                 (wenn nicht Textrahmen und nicht ContourTextFrame)
2095 // - sal_Bool ContourTextFrame         (wenn nicht Textrahmen und nicht Fontwork)
2096 // - long Drehwinkel               (wenn nicht FontWork)
2097 // - long Textrahmenabstaende      (wenn nicht FontWork)
2098 // - sal_Bool FitToSize                (wenn nicht FontWork)
2099 // - sal_Bool AutoGrowingWidth/Height  (wenn nicht FitToSize und nicht FontWork)
2100 // - long Min/MaxFrameWidth/Height (wenn AutoGrowingWidth/Height)
2101 // - enum Horizontale Textverankerung Links,Mitte,Rechts,Block,Stretch(ni)
2102 // - enum Vertikale Textverankerung Oben,Mitte,Unten,Block,Stretch(ni)
2103 // - enum Laufschrift              (wenn nicht FontWork)
2104 //
2105 // Jedes abgeleitete Objekt ist entweder ein Textrahmen (bTextFrame=sal_True)
2106 // oder ein beschriftetes Zeichenobjekt (bTextFrame=sal_False).
2107 //
2108 // Defaultverankerung von Textrahmen:
2109 //   SDRTEXTHORZADJUST_BLOCK, SDRTEXTVERTADJUST_TOP
2110 //   = statische Pooldefaults
2111 // Defaultverankerung von beschrifteten Zeichenobjekten:
2112 //   SDRTEXTHORZADJUST_CENTER, SDRTEXTVERTADJUST_CENTER
2113 //   durch harte Attributierung von SdrAttrObj
2114 //
2115 // Jedes vom SdrTextObj abgeleitete Objekt muss ein "UnrotatedSnapRect"
2116 // (->TakeUnrotatedSnapRect()) liefern (Drehreferenz ist TopLeft dieses
2117 // Rechtecks (aGeo.nDrehWink)), welches die Grundlage der Textverankerung
2118 // bildet. Von diesem werden dann ringsum die Textrahmenabstaende abgezogen;
2119 // das Ergebnis ist der Ankerbereich (->TakeTextAnchorRect()). Innerhalb
2120 // dieses Bereichs wird dann in Abhaengigkeit von der horizontalen und
2121 // vertikalen Ausrichtung (SdrTextVertAdjust,SdrTextHorzAdjust) der Ankerpunkt
2122 // sowie der Ausgabebereich bestimmt. Bei beschrifteten Grafikobjekten kann
2123 // der Ausgabebereich durchaus groesser als der Ankerbereich werden, bei
2124 // Textrahmen ist er stets kleiner oder gleich (ausser bei negativen Textrahmen-
2125 // abstaenden).
2126 //
2127 // FitToSize hat Prioritaet vor Textverankerung und AutoGrowHeight/Width. Der
2128 // Ausgabebereich ist bei FitToSize immer genau der Ankerbereich. Weiterhin
2129 // gibt es bei FitToSize keinen automatischen Zeilenumbruch.
2130 //
2131 // ContourTextFrame:
2132 // - long Drehwinkel
2133 // - long Textrahmenabstaende         spaeter vielleicht
2134 // - sal_Bool FitToSize                   spaeter vielleicht
2135 // - sal_Bool AutoGrowingWidth/Height     viel spaeter vielleicht
2136 // - long Min/MaxFrameWidth/Height    viel spaeter vielleicht
2137 // - enum Horizontale Textverankerung spaeter vielleicht, erstmal Links, Absatz zentr.
2138 // - enum Vertikale Textverankerung   spaeter vielleicht, erstmal oben
2139 // - enum Laufschrift                 spaeter vielleicht (evtl. sogar mit korrektem Clipping)
2140 //
2141 // Bei Aenderungen zu beachten:
2142 // - Paint
2143 // - HitTest
2144 // - ConvertToPoly
2145 // - Edit
2146 // - Drucken,Speichern, Paint in Nachbarview waerend Edit
2147 // - ModelChanged (z.B. durch NachbarView oder Lineale) waerend Edit
2148 // - FillColorChanged waerend Edit
2149 // - uvm...
2150 //
2151 /////////////////////////////////////////////////////////////////////////////////////////////////
2152 
2153