xref: /AOO41X/main/svx/source/svdraw/svdotext.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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
73 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
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 
91 sdr::properties::BaseProperties* SdrTextObj::CreateObjectSpecificProperties()
92 {
93     return new sdr::properties::TextProperties(*this);
94 }
95 
96 //////////////////////////////////////////////////////////////////////////////
97 // DrawContact section
98 
99 sdr::contact::ViewContact* SdrTextObj::CreateObjectSpecificViewContact()
100 {
101     return new sdr::contact::ViewContactOfTextObj(*this);
102 }
103 
104 //////////////////////////////////////////////////////////////////////////////
105 
106 TYPEINIT1(SdrTextObj,SdrAttrObj);
107 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
363 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 
384 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 
409 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 
437 SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust() const
438 {
439     return GetTextHorizontalAdjust(GetObjectItemSet());
440 }
441 
442 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 
470 SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust() const
471 {
472     return GetTextVerticalAdjust(GetObjectItemSet());
473 }
474 
475 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 
503 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 
512 void SdrTextObj::ImpCheckShear()
513 {
514     if (bNoShear && aGeo.nShearWink!=0) {
515         aGeo.nShearWink=0;
516         aGeo.nTan=0;
517     }
518 }
519 
520 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 
547 sal_uInt16 SdrTextObj::GetObjIdentifier() const
548 {
549     return sal_uInt16(eTextKind);
550 }
551 
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 
576 FASTBOOL SdrTextObj::HasEditText() const
577 {
578     return HasTextImpl( pEdtOutl );
579 }
580 
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 
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 
631 FASTBOOL SdrTextObj::NbcSetEckenradius(long nRad)
632 {
633     SetObjectItem(SdrEckenradiusItem(nRad));
634     return sal_True;
635 }
636 
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 FASTBOOL SdrTextObj::NbcSetMinTextFrameHeight(long nHgt)
648 {
649     if( bTextFrame && ( !pModel || !pModel->isLocked() ) )          // SJ: #i44922#
650     {
651         SetObjectItem(SdrTextMinFrameHeightItem(nHgt));
652 
653         // #84974# use bDisableAutoWidthOnDragging as
654         // bDisableAutoHeightOnDragging if vertical.
655         if(IsVerticalWriting() && bDisableAutoWidthOnDragging)
656         {
657             bDisableAutoWidthOnDragging = sal_False;
658             SetObjectItem(SdrTextAutoGrowHeightItem(sal_False));
659         }
660 
661         return sal_True;
662     }
663     return sal_False;
664 }
665 
666 FASTBOOL SdrTextObj::NbcSetMaxTextFrameHeight(long nHgt)
667 {
668     if(bTextFrame)
669     {
670         SetObjectItem(SdrTextMaxFrameHeightItem(nHgt));
671         return sal_True;
672     }
673     return sal_False;
674 }
675 
676 FASTBOOL SdrTextObj::NbcSetAutoGrowWidth(bool bAuto)
677 {
678     if(bTextFrame)
679     {
680         SetObjectItem(SdrTextAutoGrowWidthItem(bAuto));
681         return sal_True;
682     }
683     return sal_False;
684 }
685 
686 FASTBOOL SdrTextObj::NbcSetMinTextFrameWidth(long nWdt)
687 {
688     if( bTextFrame && ( !pModel || !pModel->isLocked() ) )          // SJ: #i44922#
689     {
690         SetObjectItem(SdrTextMinFrameWidthItem(nWdt));
691 
692         // #84974# use bDisableAutoWidthOnDragging only
693         // when not vertical.
694         if(!IsVerticalWriting() && bDisableAutoWidthOnDragging)
695         {
696             bDisableAutoWidthOnDragging = sal_False;
697             SetObjectItem(SdrTextAutoGrowWidthItem(sal_False));
698         }
699 
700         return sal_True;
701     }
702     return sal_False;
703 }
704 
705 FASTBOOL SdrTextObj::NbcSetMaxTextFrameWidth(long nWdt)
706 {
707     if(bTextFrame)
708     {
709         SetObjectItem(SdrTextMaxFrameWidthItem(nWdt));
710         return sal_True;
711     }
712     return sal_False;
713 }
714 
715 FASTBOOL SdrTextObj::NbcSetFitToSize(SdrFitToSizeType eFit)
716 {
717     if(bTextFrame)
718     {
719         SetObjectItem(SdrTextFitToSizeTypeItem(eFit));
720         return sal_True;
721     }
722     return sal_False;
723 }
724 
725 void SdrTextObj::ImpSetContourPolygon( SdrOutliner& rOutliner, Rectangle& rAnchorRect, sal_Bool bLineWidth ) const
726 {
727     basegfx::B2DPolyPolygon aXorPolyPolygon(TakeXorPoly());
728     basegfx::B2DPolyPolygon* pContourPolyPolygon = 0L;
729     basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
730         -rAnchorRect.Left(), -rAnchorRect.Top()));
731 
732     if(aGeo.nDrehWink)
733     {
734         // Unrotate!
735         aMatrix.rotate(-aGeo.nDrehWink * nPi180);
736     }
737 
738     aXorPolyPolygon.transform(aMatrix);
739 
740     if( bLineWidth )
741     {
742         // Strichstaerke beruecksichtigen
743         // Beim Hittest muss das unterbleiben (Performance!)
744         pContourPolyPolygon = new basegfx::B2DPolyPolygon();
745 
746         // #86258# test if shadow needs to be avoided for TakeContour()
747         const SfxItemSet& rSet = GetObjectItemSet();
748         sal_Bool bShadowOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
749 
750         // #i33696#
751         // Remember TextObject currently set at the DrawOutliner, it WILL be
752         // replaced during calculating the outline since it uses an own paint
753         // and that one uses the DrawOutliner, too.
754         const SdrTextObj* pLastTextObject = rOutliner.GetTextObj();
755 
756         if(bShadowOn)
757         {
758             // #86258# force shadow off
759             SdrObject* pCopy = Clone();
760             pCopy->SetMergedItem(SdrShadowItem(sal_False));
761             *pContourPolyPolygon = pCopy->TakeContour();
762             SdrObject::Free( pCopy );
763         }
764         else
765         {
766             *pContourPolyPolygon = TakeContour();
767         }
768 
769         // #i33696#
770         // restore remembered text object
771         if(pLastTextObject != rOutliner.GetTextObj())
772         {
773             rOutliner.SetTextObj(pLastTextObject);
774         }
775 
776         pContourPolyPolygon->transform(aMatrix);
777     }
778 
779     rOutliner.SetPolygon(aXorPolyPolygon, pContourPolyPolygon);
780 }
781 
782 void SdrTextObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
783 {
784     rRect=aRect;
785 }
786 
787 void SdrTextObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
788 {
789     long nLeftDist=GetTextLeftDistance();
790     long nRightDist=GetTextRightDistance();
791     long nUpperDist=GetTextUpperDistance();
792     long nLowerDist=GetTextLowerDistance();
793     Rectangle aAnkRect(aRect); // Rect innerhalb dem geankert wird
794     FASTBOOL bFrame=IsTextFrame();
795     if (!bFrame) {
796         TakeUnrotatedSnapRect(aAnkRect);
797     }
798     Point aRotateRef(aAnkRect.TopLeft());
799     aAnkRect.Left()+=nLeftDist;
800     aAnkRect.Top()+=nUpperDist;
801     aAnkRect.Right()-=nRightDist;
802     aAnkRect.Bottom()-=nLowerDist;
803 
804     // #108816#
805     // Since sizes may be bigger than the object bounds it is necessary to
806     // justify the rect now.
807     ImpJustifyRect(aAnkRect);
808 
809     if (bFrame) {
810         // !!! hier noch etwas verfeinern !!!
811         if (aAnkRect.GetWidth()<2) aAnkRect.Right()=aAnkRect.Left()+1;   // Mindestgroesse 2
812         if (aAnkRect.GetHeight()<2) aAnkRect.Bottom()=aAnkRect.Top()+1;  // Mindestgroesse 2
813     }
814     if (aGeo.nDrehWink!=0) {
815         Point aTmpPt(aAnkRect.TopLeft());
816         RotatePoint(aTmpPt,aRotateRef,aGeo.nSin,aGeo.nCos);
817         aTmpPt-=aAnkRect.TopLeft();
818         aAnkRect.Move(aTmpPt.X(),aTmpPt.Y());
819     }
820     rAnchorRect=aAnkRect;
821 }
822 
823 void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
824                                Rectangle* pAnchorRect, sal_Bool bLineWidth ) const
825 {
826     Rectangle aAnkRect; // Rect innerhalb dem geankert wird
827     TakeTextAnchorRect(aAnkRect);
828     SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
829     SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
830     SdrTextAniKind      eAniKind=GetTextAniKind();
831     SdrTextAniDirection eAniDirection=GetTextAniDirection();
832 
833     SdrFitToSizeType eFit=GetFitToSize();
834     FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
835     FASTBOOL bContourFrame=IsContourTextFrame();
836 
837     FASTBOOL bFrame=IsTextFrame();
838     sal_uIntPtr nStat0=rOutliner.GetControlWord();
839     Size aNullSize;
840     if (!bContourFrame)
841     {
842         rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
843         rOutliner.SetMinAutoPaperSize(aNullSize);
844         rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
845     }
846 
847     if (!bFitToSize && !bContourFrame)
848     {
849         long nAnkWdt=aAnkRect.GetWidth();
850         long nAnkHgt=aAnkRect.GetHeight();
851         if (bFrame)
852         {
853             long nWdt=nAnkWdt;
854             long nHgt=nAnkHgt;
855 
856             // #101684#
857             sal_Bool bInEditMode = IsInEditMode();
858 
859             if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
860             {
861                 // Grenzenlose Papiergroesse fuer Laufschrift
862                 if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nWdt=1000000;
863                 if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nHgt=1000000;
864             }
865             rOutliner.SetMaxAutoPaperSize(Size(nWdt,nHgt));
866         }
867 
868         // #103516# New try with _BLOCK for hor and ver after completely
869         // supporting full width for vertical text.
870         if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
871         {
872             rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
873         }
874 
875         if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
876         {
877             rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
878         }
879     }
880 
881     rOutliner.SetPaperSize(aNullSize);
882     if (bContourFrame)
883         ImpSetContourPolygon( rOutliner, aAnkRect, bLineWidth );
884 
885     // put text into the outliner, if available from the edit outliner
886     SdrText* pText = getActiveText();
887     OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
888     OutlinerParaObject* pPara = (pEdtOutl && !bNoEditText) ? pEdtOutl->CreateParaObject() : pOutlinerParaObject;
889 
890     if (pPara)
891     {
892         sal_Bool bHitTest = sal_False;
893         if( pModel )
894             bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
895 
896         const SdrTextObj* pTestObj = rOutliner.GetTextObj();
897         if( !pTestObj || !bHitTest || pTestObj != this ||
898             pTestObj->GetOutlinerParaObject() != pOutlinerParaObject )
899         {
900             if( bHitTest ) // #i33696# take back fix #i27510#
901             {
902                 rOutliner.SetTextObj( this );
903                 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
904             }
905 
906             rOutliner.SetUpdateMode(sal_True);
907             rOutliner.SetText(*pPara);
908         }
909     }
910     else
911     {
912         rOutliner.SetTextObj( NULL );
913     }
914 
915     if (pEdtOutl && !bNoEditText && pPara)
916         delete pPara;
917 
918     rOutliner.SetUpdateMode(sal_True);
919     rOutliner.SetControlWord(nStat0);
920 
921     if( pText )
922         pText->CheckPortionInfo(rOutliner);
923 
924     Point aTextPos(aAnkRect.TopLeft());
925     Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder?
926 
927     // #106653#
928     // For draw objects containing text correct hor/ver alignment if text is bigger
929     // than the object itself. Without that correction, the text would always be
930     // formatted to the left edge (or top edge when vertical) of the draw object.
931     if(!IsTextFrame())
932     {
933         if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
934         {
935             // #110129#
936             // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
937             // else the alignment is wanted.
938             if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
939             {
940                 eHAdj = SDRTEXTHORZADJUST_CENTER;
941             }
942         }
943 
944         if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
945         {
946             // #110129#
947             // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
948             // else the alignment is wanted.
949             if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
950             {
951                 eVAdj = SDRTEXTVERTADJUST_CENTER;
952             }
953         }
954     }
955 
956     if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
957     {
958         long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
959         if (eHAdj==SDRTEXTHORZADJUST_CENTER)
960             aTextPos.X()+=nFreeWdt/2;
961         if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
962             aTextPos.X()+=nFreeWdt;
963     }
964     if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
965     {
966         long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
967         if (eVAdj==SDRTEXTVERTADJUST_CENTER)
968             aTextPos.Y()+=nFreeHgt/2;
969         if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
970             aTextPos.Y()+=nFreeHgt;
971     }
972     if (aGeo.nDrehWink!=0)
973         RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
974 
975     if (pAnchorRect)
976         *pAnchorRect=aAnkRect;
977 
978     // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt
979     rTextRect=Rectangle(aTextPos,aTextSiz);
980     if (bContourFrame)
981         rTextRect=aAnkRect;
982 }
983 
984 OutlinerParaObject* SdrTextObj::GetEditOutlinerParaObject() const
985 {
986     OutlinerParaObject* pPara=NULL;
987     if( HasTextImpl( pEdtOutl ) )
988     {
989         sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( pEdtOutl->GetParagraphCount() );
990         pPara = pEdtOutl->CreateParaObject(0, nParaAnz);
991     }
992     return pPara;
993 }
994 
995 void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Rectangle& rTextRect, const Rectangle& rAnchorRect, Fraction& rFitXKorreg) const
996 {
997     OutputDevice* pOut = rOutliner.GetRefDevice();
998     sal_Bool bNoStretching(sal_False);
999 
1000     if(pOut && pOut->GetOutDevType() == OUTDEV_PRINTER)
1001     {
1002         // #35762#: Checken ob CharStretching ueberhaupt moeglich
1003         GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
1004         UniString aTestString(sal_Unicode('J'));
1005 
1006         if(pMtf && (!pMtf->IsRecord() || pMtf->IsPause()))
1007             pMtf = NULL;
1008 
1009         if(pMtf)
1010             pMtf->Pause(sal_True);
1011 
1012         Font aFontMerk(pOut->GetFont());
1013         Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ) );
1014 
1015         aTmpFont.SetSize(Size(0,100));
1016         pOut->SetFont(aTmpFont);
1017         Size aSize1(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
1018         aTmpFont.SetSize(Size(800,100));
1019         pOut->SetFont(aTmpFont);
1020         Size aSize2(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
1021         pOut->SetFont(aFontMerk);
1022 
1023         if(pMtf)
1024             pMtf->Pause(sal_False);
1025 
1026         bNoStretching = (aSize1 == aSize2);
1027 
1028 #ifdef WNT
1029         // #35762# Windows vergroessert bei Size(100,500) den Font proportional
1030         // Und das finden wir nicht so schoen.
1031         if(aSize2.Height() >= aSize1.Height() * 2)
1032         {
1033             bNoStretching = sal_True;
1034         }
1035 #endif
1036     }
1037     unsigned nLoopCount=0;
1038     FASTBOOL bNoMoreLoop=sal_False;
1039     long nXDiff0=0x7FFFFFFF;
1040     long nWantWdt=rAnchorRect.Right()-rAnchorRect.Left();
1041     long nIsWdt=rTextRect.Right()-rTextRect.Left();
1042     if (nIsWdt==0) nIsWdt=1;
1043 
1044     long nWantHgt=rAnchorRect.Bottom()-rAnchorRect.Top();
1045     long nIsHgt=rTextRect.Bottom()-rTextRect.Top();
1046     if (nIsHgt==0) nIsHgt=1;
1047 
1048     long nXTolPl=nWantWdt/100; // Toleranz +1%
1049     long nXTolMi=nWantWdt/25;  // Toleranz -4%
1050     long nXKorr =nWantWdt/20;  // Korrekturmasstab 5%
1051 
1052     long nX=(nWantWdt*100) /nIsWdt; // X-Stretching berechnen
1053     long nY=(nWantHgt*100) /nIsHgt; // Y-Stretching berechnen
1054     FASTBOOL bChkX=sal_True;
1055     FASTBOOL bChkY=sal_True;
1056     if (bNoStretching) { // #35762# evtl. nur proportional moeglich
1057         if (nX>nY) { nX=nY; bChkX=sal_False; }
1058         else { nY=nX; bChkY=sal_False; }
1059     }
1060 
1061     while (nLoopCount<5 && !bNoMoreLoop) {
1062         if (nX<0) nX=-nX;
1063         if (nX<1) { nX=1; bNoMoreLoop=sal_True; }
1064         if (nX>65535) { nX=65535; bNoMoreLoop=sal_True; }
1065 
1066         if (nY<0) nY=-nY;
1067         if (nY<1) { nY=1; bNoMoreLoop=sal_True; }
1068         if (nY>65535) { nY=65535; bNoMoreLoop=sal_True; }
1069 
1070         // exception, there is no text yet (horizontal case)
1071         if(nIsWdt <= 1)
1072         {
1073             nX = nY;
1074             bNoMoreLoop = sal_True;
1075         }
1076 
1077         // #87877# exception, there is no text yet (vertical case)
1078         if(nIsHgt <= 1)
1079         {
1080             nY = nX;
1081             bNoMoreLoop = sal_True;
1082         }
1083 
1084         rOutliner.SetGlobalCharStretching((sal_uInt16)nX,(sal_uInt16)nY);
1085         nLoopCount++;
1086         Size aSiz(rOutliner.CalcTextSize());
1087         long nXDiff=aSiz.Width()-nWantWdt;
1088         rFitXKorreg=Fraction(nWantWdt,aSiz.Width());
1089         if (((nXDiff>=nXTolMi || !bChkX) && nXDiff<=nXTolPl) || nXDiff==nXDiff0/*&& Abs(nYDiff)<=nYTol*/) {
1090             bNoMoreLoop=sal_True;
1091         } else {
1092             // Stretchingfaktoren korregieren
1093             long nMul=nWantWdt;
1094             long nDiv=aSiz.Width();
1095             if (Abs(nXDiff)<=2*nXKorr) {
1096                 if (nMul>nDiv) nDiv+=(nMul-nDiv)/2; // und zwar nur um die haelfte des berechneten
1097                 else nMul+=(nDiv-nMul)/2;           // weil die EE ja eh wieder falsch rechnet
1098             }
1099             nX=nX*nMul/nDiv;
1100             if (bNoStretching) nY=nX;
1101         }
1102         nXDiff0=nXDiff;
1103     }
1104 }
1105 
1106 void SdrTextObj::StartTextAnimation(OutputDevice* /*pOutDev*/, const Point& /*rOffset*/, long /*nExtraData*/)
1107 {
1108     // #111096#
1109     // use new text animation
1110     SetTextAnimationAllowed(sal_True);
1111 }
1112 
1113 void SdrTextObj::StopTextAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
1114 {
1115     // #111096#
1116     // use new text animation
1117     SetTextAnimationAllowed(sal_False);
1118 }
1119 
1120 void SdrTextObj::TakeObjNameSingul(XubString& rName) const
1121 {
1122     XubString aStr;
1123 
1124     switch(eTextKind)
1125     {
1126         case OBJ_OUTLINETEXT:
1127         {
1128             aStr = ImpGetResStr(STR_ObjNameSingulOUTLINETEXT);
1129             break;
1130         }
1131 
1132         case OBJ_TITLETEXT  :
1133         {
1134             aStr = ImpGetResStr(STR_ObjNameSingulTITLETEXT);
1135             break;
1136         }
1137 
1138         default:
1139         {
1140             if(IsLinkedText())
1141                 aStr = ImpGetResStr(STR_ObjNameSingulTEXTLNK);
1142             else
1143                 aStr = ImpGetResStr(STR_ObjNameSingulTEXT);
1144             break;
1145         }
1146     }
1147 
1148     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1149     if(pOutlinerParaObject && eTextKind != OBJ_OUTLINETEXT)
1150     {
1151         // Macht bei OUTLINETEXT wohl derzeit noch etwas Probleme
1152         XubString aStr2(pOutlinerParaObject->GetTextObject().GetText(0));
1153         aStr2.EraseLeadingChars();
1154 
1155         // #69446# avoid non expanded text portions in object name
1156         // (second condition is new)
1157         if(aStr2.Len() && aStr2.Search(sal_Unicode(255)) == STRING_NOTFOUND)
1158         {
1159             // #76681# space between ResStr and content text
1160             aStr += sal_Unicode(' ');
1161 
1162             aStr += sal_Unicode('\'');
1163 
1164             if(aStr2.Len() > 10)
1165             {
1166                 aStr2.Erase(8);
1167                 aStr2.AppendAscii("...", 3);
1168             }
1169 
1170             aStr += aStr2;
1171             aStr += sal_Unicode('\'');
1172         }
1173     }
1174 
1175     rName = aStr;
1176 
1177     String aName( GetName() );
1178     if(aName.Len())
1179     {
1180         rName += sal_Unicode(' ');
1181         rName += sal_Unicode('\'');
1182         rName += aName;
1183         rName += sal_Unicode('\'');
1184     }
1185 
1186 }
1187 
1188 void SdrTextObj::TakeObjNamePlural(XubString& rName) const
1189 {
1190     switch (eTextKind) {
1191         case OBJ_OUTLINETEXT: rName=ImpGetResStr(STR_ObjNamePluralOUTLINETEXT); break;
1192         case OBJ_TITLETEXT  : rName=ImpGetResStr(STR_ObjNamePluralTITLETEXT);   break;
1193         default: {
1194             if (IsLinkedText()) {
1195                 rName=ImpGetResStr(STR_ObjNamePluralTEXTLNK);
1196             } else {
1197                 rName=ImpGetResStr(STR_ObjNamePluralTEXT);
1198             }
1199         } break;
1200     } // switch
1201 }
1202 
1203 void SdrTextObj::operator=(const SdrObject& rObj)
1204 {
1205     // call parent
1206     SdrObject::operator=(rObj);
1207 
1208     const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >( &rObj );
1209     if (pTextObj!=NULL)
1210     {
1211         aRect     =pTextObj->aRect;
1212         aGeo      =pTextObj->aGeo;
1213         eTextKind =pTextObj->eTextKind;
1214         bTextFrame=pTextObj->bTextFrame;
1215         aTextSize=pTextObj->aTextSize;
1216         bTextSizeDirty=pTextObj->bTextSizeDirty;
1217 
1218         // #101776# Not all of the necessary parameters were copied yet.
1219         bNoShear = pTextObj->bNoShear;
1220         bNoRotate = pTextObj->bNoRotate;
1221         bNoMirror = pTextObj->bNoMirror;
1222         bDisableAutoWidthOnDragging = pTextObj->bDisableAutoWidthOnDragging;
1223 
1224         OutlinerParaObject* pNewOutlinerParaObject = 0;
1225 
1226         SdrText* pText = getActiveText();
1227 
1228         if( pText && pTextObj->HasText() )
1229         {
1230             const Outliner* pEO=pTextObj->pEdtOutl;
1231             if (pEO!=NULL)
1232             {
1233                 pNewOutlinerParaObject = pEO->CreateParaObject();
1234             }
1235             else
1236             {
1237                 pNewOutlinerParaObject = new OutlinerParaObject(*pTextObj->getActiveText()->GetOutlinerParaObject());
1238             }
1239         }
1240 
1241         mpText->SetOutlinerParaObject( pNewOutlinerParaObject );
1242         ImpSetTextStyleSheetListeners();
1243     }
1244 }
1245 
1246 basegfx::B2DPolyPolygon SdrTextObj::TakeXorPoly() const
1247 {
1248     Polygon aPol(aRect);
1249     if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1250     if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1251 
1252     basegfx::B2DPolyPolygon aRetval;
1253     aRetval.append(aPol.getB2DPolygon());
1254     return aRetval;
1255 }
1256 
1257 basegfx::B2DPolyPolygon SdrTextObj::TakeContour() const
1258 {
1259     basegfx::B2DPolyPolygon aRetval(SdrAttrObj::TakeContour());
1260 
1261     // und nun noch ggf. das BoundRect des Textes dazu
1262     if ( pModel && GetOutlinerParaObject() && !IsFontwork() && !IsContourTextFrame() )
1263     {
1264         // #80328# using Clone()-Paint() strategy inside TakeContour() leaves a destroyed
1265         // SdrObject as pointer in DrawOutliner. Set *this again in fetching the outliner
1266         // in every case
1267         SdrOutliner& rOutliner=ImpGetDrawOutliner();
1268 
1269         Rectangle aAnchor2;
1270         Rectangle aR;
1271         TakeTextRect(rOutliner,aR,sal_False,&aAnchor2);
1272         rOutliner.Clear();
1273         SdrFitToSizeType eFit=GetFitToSize();
1274         FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
1275         if (bFitToSize) aR=aAnchor2;
1276         Polygon aPol(aR);
1277         if (aGeo.nDrehWink!=0) RotatePoly(aPol,aR.TopLeft(),aGeo.nSin,aGeo.nCos);
1278 
1279         aRetval.append(aPol.getB2DPolygon());
1280     }
1281 
1282     return aRetval;
1283 }
1284 
1285 void SdrTextObj::RecalcSnapRect()
1286 {
1287     if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) {
1288         Polygon aPol(aRect);
1289         if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1290         if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1291         maSnapRect=aPol.GetBoundRect();
1292     } else {
1293         maSnapRect=aRect;
1294     }
1295 }
1296 
1297 sal_uInt32 SdrTextObj::GetSnapPointCount() const
1298 {
1299     return 4L;
1300 }
1301 
1302 Point SdrTextObj::GetSnapPoint(sal_uInt32 i) const
1303 {
1304     Point aP;
1305     switch (i) {
1306         case 0: aP=aRect.TopLeft(); break;
1307         case 1: aP=aRect.TopRight(); break;
1308         case 2: aP=aRect.BottomLeft(); break;
1309         case 3: aP=aRect.BottomRight(); break;
1310         default: aP=aRect.Center(); break;
1311     }
1312     if (aGeo.nShearWink!=0) ShearPoint(aP,aRect.TopLeft(),aGeo.nTan);
1313     if (aGeo.nDrehWink!=0) RotatePoint(aP,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1314     return aP;
1315 }
1316 
1317 void SdrTextObj::ImpCheckMasterCachable()
1318 {
1319     bNotMasterCachable=sal_False;
1320 
1321     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1322 
1323     if(!bNotVisibleAsMaster && pOutlinerParaObject && pOutlinerParaObject->IsEditDoc() )
1324     {
1325         const EditTextObject& rText= pOutlinerParaObject->GetTextObject();
1326         bNotMasterCachable=rText.HasField(SvxPageField::StaticType());
1327         if( !bNotMasterCachable )
1328         {
1329             bNotMasterCachable=rText.HasField(SvxHeaderField::StaticType());
1330             if( !bNotMasterCachable )
1331             {
1332                 bNotMasterCachable=rText.HasField(SvxFooterField::StaticType());
1333                 if( !bNotMasterCachable )
1334                 {
1335                     bNotMasterCachable=rText.HasField(SvxDateTimeField::StaticType());
1336                 }
1337             }
1338         }
1339     }
1340 }
1341 
1342 // #101029#: Extracted from ImpGetDrawOutliner()
1343 void SdrTextObj::ImpInitDrawOutliner( SdrOutliner& rOutl ) const
1344 {
1345     rOutl.SetUpdateMode(sal_False);
1346     sal_uInt16 nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
1347     if ( !IsOutlText() )
1348         nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
1349     rOutl.Init( nOutlinerMode );
1350 
1351     rOutl.SetGlobalCharStretching(100,100);
1352     sal_uIntPtr nStat=rOutl.GetControlWord();
1353     nStat&=~(EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE);
1354     rOutl.SetControlWord(nStat);
1355     Size aNullSize;
1356     Size aMaxSize(100000,100000);
1357     rOutl.SetMinAutoPaperSize(aNullSize);
1358     rOutl.SetMaxAutoPaperSize(aMaxSize);
1359     rOutl.SetPaperSize(aMaxSize);
1360     rOutl.ClearPolygon();
1361 }
1362 
1363 SdrOutliner& SdrTextObj::ImpGetDrawOutliner() const
1364 {
1365     SdrOutliner& rOutl=pModel->GetDrawOutliner(this);
1366 
1367     // #101029#: Code extracted to ImpInitDrawOutliner()
1368     ImpInitDrawOutliner( rOutl );
1369 
1370     return rOutl;
1371 }
1372 
1373 boost::shared_ptr< SdrOutliner > SdrTextObj::CreateDrawOutliner()
1374 {
1375     boost::shared_ptr< SdrOutliner > xDrawOutliner( pModel->CreateDrawOutliner(this) );
1376     ImpInitDrawOutliner( *(xDrawOutliner.get()) );
1377     return xDrawOutliner;
1378 }
1379 
1380 // #101029#: Extracted from Paint()
1381 void SdrTextObj::ImpSetupDrawOutlinerForPaint( FASTBOOL         bContourFrame,
1382                                                SdrOutliner&     rOutliner,
1383                                                Rectangle&       rTextRect,
1384                                                Rectangle&       rAnchorRect,
1385                                                Rectangle&       rPaintRect,
1386                                                Fraction&        rFitXKorreg ) const
1387 {
1388     if (!bContourFrame)
1389     {
1390         // FitToSize erstmal nicht mit ContourFrame
1391         SdrFitToSizeType eFit=GetFitToSize();
1392         if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
1393         {
1394             sal_uIntPtr nStat=rOutliner.GetControlWord();
1395             nStat|=EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE;
1396             rOutliner.SetControlWord(nStat);
1397         }
1398     }
1399     rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
1400     TakeTextRect(rOutliner, rTextRect, sal_False, &rAnchorRect);
1401     rPaintRect = rTextRect;
1402 
1403     if (!bContourFrame)
1404     {
1405         // FitToSize erstmal nicht mit ContourFrame
1406         SdrFitToSizeType eFit=GetFitToSize();
1407         if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
1408         {
1409             ImpSetCharStretching(rOutliner,rTextRect,rAnchorRect,rFitXKorreg);
1410             rPaintRect=rAnchorRect;
1411         }
1412     }
1413 }
1414 
1415 void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1416 {
1417     ImpInitDrawOutliner( rOutl );
1418     UpdateOutlinerFormatting( rOutl, rPaintRect );
1419 }
1420 
1421 void SdrTextObj::UpdateOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1422 {
1423     Rectangle aTextRect;
1424     Rectangle aAnchorRect;
1425     Fraction aFitXKorreg(1,1);
1426 
1427     FASTBOOL bContourFrame=IsContourTextFrame();
1428 
1429     if( GetModel() )
1430     {
1431         MapMode aMapMode(GetModel()->GetScaleUnit(), Point(0,0),
1432                          GetModel()->GetScaleFraction(),
1433                          GetModel()->GetScaleFraction());
1434         rOutl.SetRefMapMode(aMapMode);
1435     }
1436 
1437     ImpSetupDrawOutlinerForPaint( bContourFrame, rOutl, aTextRect, aAnchorRect, rPaintRect, aFitXKorreg );
1438 }
1439 
1440 ////////////////////////////////////////////////////////////////////////////////////////////////////
1441 
1442 OutlinerParaObject* SdrTextObj::GetOutlinerParaObject() const
1443 {
1444     SdrText* pText = getActiveText();
1445     if( pText )
1446         return pText->GetOutlinerParaObject();
1447     else
1448         return 0;
1449 }
1450 
1451 bool SdrTextObj::HasOutlinerParaObject() const
1452 {
1453     SdrText* pText = getActiveText();
1454     if( pText && pText->GetOutlinerParaObject() )
1455         return true;
1456     return false;
1457 }
1458 
1459 void SdrTextObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
1460 {
1461     NbcSetOutlinerParaObjectForText( pTextObject, getActiveText() );
1462 }
1463 
1464 void SdrTextObj::NbcSetOutlinerParaObjectForText( OutlinerParaObject* pTextObject, SdrText* pText )
1465 {
1466     if( pText )
1467         pText->SetOutlinerParaObject( pTextObject );
1468 
1469     if( pText->GetOutlinerParaObject() )
1470     {
1471         SvxWritingModeItem aWritingMode(pText->GetOutlinerParaObject()->IsVertical()
1472             ? com::sun::star::text::WritingMode_TB_RL
1473             : com::sun::star::text::WritingMode_LR_TB,
1474             SDRATTR_TEXTDIRECTION);
1475         GetProperties().SetObjectItemDirect(aWritingMode);
1476     }
1477 
1478     SetTextSizeDirty();
1479     if (IsTextFrame() && (IsAutoGrowHeight() || IsAutoGrowWidth()))
1480     { // Textrahmen anpassen!
1481         NbcAdjustTextFrameWidthAndHeight();
1482     }
1483     if (!IsTextFrame())
1484     {
1485         // Das SnapRect behaelt seine Groesse bei
1486         SetRectsDirty(sal_True);
1487     }
1488 
1489     // always invalidate BoundRect on change
1490     SetBoundRectDirty();
1491     ActionChanged();
1492 
1493     ImpSetTextStyleSheetListeners();
1494     ImpCheckMasterCachable();
1495 }
1496 
1497 void SdrTextObj::NbcReformatText()
1498 {
1499     SdrText* pText = getActiveText();
1500     if( pText && pText->GetOutlinerParaObject() )
1501     {
1502         pText->ReformatText();
1503         if (bTextFrame)
1504         {
1505             NbcAdjustTextFrameWidthAndHeight();
1506         }
1507         else
1508         {
1509             // Das SnapRect behaelt seine Groesse bei
1510             SetBoundRectDirty();
1511             SetRectsDirty(sal_True);
1512         }
1513         SetTextSizeDirty();
1514         ActionChanged();
1515         // FME, AW: i22396
1516         // Necessary here since we have no compare operator at the outliner
1517         // para object which may detect changes regarding the combination
1518         // of outliner para data and configuration (e.g., change of
1519         // formatting of text numerals)
1520         GetViewContact().flushViewObjectContacts(false);
1521     }
1522 }
1523 
1524 void SdrTextObj::ReformatText()
1525 {
1526     if(GetOutlinerParaObject())
1527     {
1528         Rectangle aBoundRect0;
1529         if (pUserCall!=NULL)
1530             aBoundRect0=GetLastBoundRect();
1531 
1532         // #110094#-14 SendRepaintBroadcast();
1533         NbcReformatText();
1534         SetChanged();
1535         BroadcastObjectChange();
1536         SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1537     }
1538 }
1539 
1540 SdrObjGeoData* SdrTextObj::NewGeoData() const
1541 {
1542     return new SdrTextObjGeoData;
1543 }
1544 
1545 void SdrTextObj::SaveGeoData(SdrObjGeoData& rGeo) const
1546 {
1547     SdrAttrObj::SaveGeoData(rGeo);
1548     SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1549     rTGeo.aRect  =aRect;
1550     rTGeo.aGeo   =aGeo;
1551 }
1552 
1553 void SdrTextObj::RestGeoData(const SdrObjGeoData& rGeo)
1554 { // RectsDirty wird von SdrObject gerufen
1555     SdrAttrObj::RestGeoData(rGeo);
1556     SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1557     aRect  =rTGeo.aRect;
1558     aGeo   =rTGeo.aGeo;
1559     SetTextSizeDirty();
1560 }
1561 
1562 SdrFitToSizeType SdrTextObj::GetFitToSize() const
1563 {
1564     SdrFitToSizeType eType = SDRTEXTFIT_NONE;
1565 
1566     if(!IsAutoGrowWidth())
1567         eType = ((SdrTextFitToSizeTypeItem&)(GetObjectItem(SDRATTR_TEXT_FITTOSIZE))).GetValue();
1568 
1569     return eType;
1570 }
1571 
1572 void SdrTextObj::ForceOutlinerParaObject()
1573 {
1574     SdrText* pText = getActiveText();
1575     if( pText && (pText->GetOutlinerParaObject() == 0) )
1576     {
1577         sal_uInt16 nOutlMode = OUTLINERMODE_TEXTOBJECT;
1578         if( IsTextFrame() && eTextKind == OBJ_OUTLINETEXT )
1579             nOutlMode = OUTLINERMODE_OUTLINEOBJECT;
1580 
1581         pText->ForceOutlinerParaObject( nOutlMode );
1582     }
1583 }
1584 
1585 sal_Bool SdrTextObj::IsVerticalWriting() const
1586 {
1587     // #89459#
1588     if(pEdtOutl)
1589     {
1590         return pEdtOutl->IsVertical();
1591     }
1592 
1593     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1594     if(pOutlinerParaObject)
1595     {
1596         return pOutlinerParaObject->IsVertical();
1597     }
1598 
1599     return sal_False;
1600 }
1601 
1602 void SdrTextObj::SetVerticalWriting(sal_Bool bVertical)
1603 {
1604     OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1605     if( !pOutlinerParaObject && bVertical )
1606     {
1607         // we only need to force a outliner para object if the default of
1608         // horizontal text is changed
1609         ForceOutlinerParaObject();
1610         pOutlinerParaObject = GetOutlinerParaObject();
1611     }
1612 
1613     if( pOutlinerParaObject && (pOutlinerParaObject->IsVertical() != (bool)bVertical) )
1614     {
1615         // get item settings
1616         const SfxItemSet& rSet = GetObjectItemSet();
1617         sal_Bool bAutoGrowWidth = ((SdrTextAutoGrowWidthItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH)).GetValue();
1618         sal_Bool bAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue();
1619 
1620         // #103516# Also exchange hor/ver adjust items
1621         SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
1622         SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
1623 
1624         // rescue object size
1625         Rectangle aObjectRect = GetSnapRect();
1626 
1627         // prepare ItemSet to set exchanged width and height items
1628         SfxItemSet aNewSet(*rSet.GetPool(),
1629             SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
1630             // #103516# Expanded item ranges to also support hor and ver adjust.
1631             SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
1632             SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
1633             0, 0);
1634 
1635         aNewSet.Put(rSet);
1636         aNewSet.Put(SdrTextAutoGrowWidthItem(bAutoGrowHeight));
1637         aNewSet.Put(SdrTextAutoGrowHeightItem(bAutoGrowWidth));
1638 
1639         // #103516# Exchange horz and vert adjusts
1640         switch(eVert)
1641         {
1642             case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
1643             case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
1644             case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
1645             case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
1646         }
1647         switch(eHorz)
1648         {
1649             case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
1650             case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
1651             case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
1652             case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
1653         }
1654 
1655         SetObjectItemSet(aNewSet);
1656 
1657         pOutlinerParaObject = GetOutlinerParaObject();
1658         if( pOutlinerParaObject )
1659         {
1660             // set ParaObject orientation accordingly
1661             pOutlinerParaObject->SetVertical(bVertical);
1662         }
1663 
1664         // restore object size
1665         SetSnapRect(aObjectRect);
1666     }
1667 }
1668 
1669 ////////////////////////////////////////////////////////////////////////////////////////////////////
1670 //
1671 // transformation interface for StarOfficeAPI. This implements support for
1672 // homogen 3x3 matrices containing the transformation of the SdrObject. At the
1673 // moment it contains a shearX, rotation and translation, but for setting all linear
1674 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
1675 //
1676 ////////////////////////////////////////////////////////////////////////////////////////////////////
1677 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
1678 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
1679 sal_Bool SdrTextObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
1680 {
1681     // get turn and shear
1682     double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
1683     double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
1684 
1685     // get aRect, this is the unrotated snaprect
1686     Rectangle aRectangle(aRect);
1687 
1688     // fill other values
1689     basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
1690     basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
1691 
1692     // position maybe relative to anchorpos, convert
1693     if( pModel && pModel->IsWriter() )
1694     {
1695         if(GetAnchorPos().X() || GetAnchorPos().Y())
1696         {
1697             aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1698         }
1699     }
1700 
1701     // force MapUnit to 100th mm
1702     SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
1703     if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1704     {
1705         switch(eMapUnit)
1706         {
1707             case SFX_MAPUNIT_TWIP :
1708             {
1709                 // postion
1710                 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
1711                 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
1712 
1713                 // size
1714                 aScale.setX(ImplTwipsToMM(aScale.getX()));
1715                 aScale.setY(ImplTwipsToMM(aScale.getY()));
1716 
1717                 break;
1718             }
1719             default:
1720             {
1721                 DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
1722             }
1723         }
1724     }
1725 
1726     // build matrix
1727     rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
1728         aScale,
1729         basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
1730         basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
1731         aTranslate);
1732 
1733     return sal_False;
1734 }
1735 
1736 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
1737 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
1738 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
1739 void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
1740 {
1741     // break up matrix
1742     basegfx::B2DTuple aScale;
1743     basegfx::B2DTuple aTranslate;
1744     double fRotate(0.0);
1745     double fShearX(0.0);
1746     rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1747 
1748     // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
1749     // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
1750     if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
1751     {
1752         aScale.setX(fabs(aScale.getX()));
1753         aScale.setY(fabs(aScale.getY()));
1754         fRotate = fmod(fRotate + F_PI, F_2PI);
1755     }
1756 
1757     // reset object shear and rotations
1758     aGeo.nDrehWink = 0;
1759     aGeo.RecalcSinCos();
1760     aGeo.nShearWink = 0;
1761     aGeo.RecalcTan();
1762 
1763     // force metric to pool metric
1764     SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
1765     if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1766     {
1767         switch(eMapUnit)
1768         {
1769             case SFX_MAPUNIT_TWIP :
1770             {
1771                 // position
1772                 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
1773                 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
1774 
1775                 // size
1776                 aScale.setX(ImplMMToTwips(aScale.getX()));
1777                 aScale.setY(ImplMMToTwips(aScale.getY()));
1778 
1779                 break;
1780             }
1781             default:
1782             {
1783                 DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
1784             }
1785         }
1786     }
1787 
1788     // if anchor is used, make position relative to it
1789     if( pModel && pModel->IsWriter() )
1790     {
1791         if(GetAnchorPos().X() || GetAnchorPos().Y())
1792         {
1793             aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1794         }
1795     }
1796 
1797     // build and set BaseRect (use scale)
1798     Point aPoint = Point();
1799     Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
1800     Rectangle aBaseRect(aPoint, aSize);
1801     SetSnapRect(aBaseRect);
1802 
1803     // shear?
1804     if(!basegfx::fTools::equalZero(fShearX))
1805     {
1806         GeoStat aGeoStat;
1807         aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
1808         aGeoStat.RecalcTan();
1809         Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, sal_False);
1810     }
1811 
1812     // rotation?
1813     if(!basegfx::fTools::equalZero(fRotate))
1814     {
1815         GeoStat aGeoStat;
1816 
1817         // #i78696#
1818         // fRotate is matematically correct, but aGeoStat.nDrehWink is
1819         // mirrored -> mirror value here
1820         aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
1821         aGeoStat.RecalcSinCos();
1822         Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1823     }
1824 
1825     // translate?
1826     if(!aTranslate.equalZero())
1827     {
1828         Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
1829     }
1830 }
1831 
1832 bool SdrTextObj::IsRealyEdited() const
1833 {
1834     return pEdtOutl && pEdtOutl->IsModified();
1835 }
1836 
1837 /////////////////////////////////////////////////////////////////////////////////////////////////
1838 // moved inlines here form hxx
1839 
1840 long SdrTextObj::GetEckenradius() const
1841 {
1842     return ((SdrEckenradiusItem&)(GetObjectItemSet().Get(SDRATTR_ECKENRADIUS))).GetValue();
1843 }
1844 
1845 long SdrTextObj::GetMinTextFrameHeight() const
1846 {
1847     return ((SdrTextMinFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEHEIGHT))).GetValue();
1848 }
1849 
1850 long SdrTextObj::GetMaxTextFrameHeight() const
1851 {
1852     return ((SdrTextMaxFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEHEIGHT))).GetValue();
1853 }
1854 
1855 long SdrTextObj::GetMinTextFrameWidth() const
1856 {
1857     return ((SdrTextMinFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEWIDTH))).GetValue();
1858 }
1859 
1860 long SdrTextObj::GetMaxTextFrameWidth() const
1861 {
1862     return ((SdrTextMaxFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEWIDTH))).GetValue();
1863 }
1864 
1865 FASTBOOL SdrTextObj::IsFontwork() const
1866 {
1867     return (bTextFrame) ? sal_False // Default ist FALSE
1868         : ((XFormTextStyleItem&)(GetObjectItemSet().Get(XATTR_FORMTXTSTYLE))).GetValue()!=XFT_NONE;
1869 }
1870 
1871 FASTBOOL SdrTextObj::IsHideContour() const
1872 {
1873     return (bTextFrame) ? sal_False // Default ist: Nein, kein HideContour; HideContour nicht bei TextFrames
1874         : ((XFormTextHideFormItem&)(GetObjectItemSet().Get(XATTR_FORMTXTHIDEFORM))).GetValue();
1875 }
1876 
1877 FASTBOOL SdrTextObj::IsContourTextFrame() const
1878 {
1879     return (bTextFrame) ? sal_False // ContourFrame nicht bei normalen TextFrames
1880         : ((SdrTextContourFrameItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_CONTOURFRAME))).GetValue();
1881 }
1882 
1883 long SdrTextObj::GetTextLeftDistance() const
1884 {
1885     return ((SdrTextLeftDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LEFTDIST))).GetValue();
1886 }
1887 
1888 long SdrTextObj::GetTextRightDistance() const
1889 {
1890     return ((SdrTextRightDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_RIGHTDIST))).GetValue();
1891 }
1892 
1893 long SdrTextObj::GetTextUpperDistance() const
1894 {
1895     return ((SdrTextUpperDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_UPPERDIST))).GetValue();
1896 }
1897 
1898 long SdrTextObj::GetTextLowerDistance() const
1899 {
1900     return ((SdrTextLowerDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LOWERDIST))).GetValue();
1901 }
1902 
1903 SdrTextAniKind SdrTextObj::GetTextAniKind() const
1904 {
1905     return ((SdrTextAniKindItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIKIND))).GetValue();
1906 }
1907 
1908 SdrTextAniDirection SdrTextObj::GetTextAniDirection() const
1909 {
1910     return ((SdrTextAniDirectionItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
1911 }
1912 
1913 // #111096#
1914 // Access to thext hidden flag
1915 sal_Bool SdrTextObj::GetTextHidden() const
1916 {
1917     return mbTextHidden;
1918 }
1919 
1920 void SdrTextObj::NbcSetTextHidden(sal_Bool bNew)
1921 {
1922     if(bNew != mbTextHidden)
1923     {
1924         mbTextHidden = bNew;
1925     }
1926 }
1927 
1928 // #111096#
1929 // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a
1930 // painting rectangle. Rotation is excluded from the returned values.
1931 GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle(
1932     Rectangle& rScrollRectangle, Rectangle& rPaintRectangle)
1933 {
1934     GDIMetaFile* pRetval = 0L;
1935     SdrOutliner& rOutliner = ImpGetDrawOutliner();
1936     Rectangle aTextRect;
1937     Rectangle aAnchorRect;
1938     Rectangle aPaintRect;
1939     Fraction aFitXKorreg(1,1);
1940     bool bContourFrame(IsContourTextFrame());
1941 
1942     // get outliner set up. To avoid getting a somehow rotated MetaFile,
1943     // temporarily disable object rotation.
1944     sal_Int32 nAngle(aGeo.nDrehWink);
1945     aGeo.nDrehWink = 0L;
1946     ImpSetupDrawOutlinerForPaint( bContourFrame, rOutliner, aTextRect, aAnchorRect, aPaintRect, aFitXKorreg );
1947     aGeo.nDrehWink = nAngle;
1948 
1949     Rectangle aScrollFrameRect(aPaintRect);
1950     const SfxItemSet& rSet = GetObjectItemSet();
1951     SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
1952 
1953     if(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection)
1954     {
1955         aScrollFrameRect.Left() = aAnchorRect.Left();
1956         aScrollFrameRect.Right() = aAnchorRect.Right();
1957     }
1958 
1959     if(SDRTEXTANI_UP == eDirection || SDRTEXTANI_DOWN == eDirection)
1960     {
1961         aScrollFrameRect.Top() = aAnchorRect.Top();
1962         aScrollFrameRect.Bottom() = aAnchorRect.Bottom();
1963     }
1964 
1965     // create the MetaFile
1966     pRetval = new GDIMetaFile;
1967     VirtualDevice aBlackHole;
1968     aBlackHole.EnableOutput(sal_False);
1969     pRetval->Record(&aBlackHole);
1970     Point aPaintPos = aPaintRect.TopLeft();
1971 
1972     rOutliner.Draw(&aBlackHole, aPaintPos);
1973 
1974     pRetval->Stop();
1975     pRetval->WindStart();
1976 
1977     // return PaintRectanglePixel and pRetval;
1978     rScrollRectangle = aScrollFrameRect;
1979     rPaintRectangle = aPaintRect;
1980 
1981     return pRetval;
1982 }
1983 
1984 // #111096#
1985 // Access to TextAnimationAllowed flag
1986 bool SdrTextObj::IsTextAnimationAllowed() const
1987 {
1988     return mbTextAnimationAllowed;
1989 }
1990 
1991 void SdrTextObj::SetTextAnimationAllowed(sal_Bool bNew)
1992 {
1993     if(mbTextAnimationAllowed != bNew)
1994     {
1995         mbTextAnimationAllowed = bNew;
1996         ActionChanged();
1997     }
1998 }
1999 
2000 /** called from the SdrObjEditView during text edit when the status of the edit outliner changes */
2001 void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
2002 {
2003     const sal_uInt32 nStat = pEditStatus->GetStatusWord();
2004     const bool bGrowX=(nStat & EE_STAT_TEXTWIDTHCHANGED) !=0;
2005     const bool bGrowY=(nStat & EE_STAT_TEXTHEIGHTCHANGED) !=0;
2006     if(bTextFrame && (bGrowX || bGrowY))
2007     {
2008         const bool bAutoGrowHgt= bTextFrame && IsAutoGrowHeight();
2009         const bool bAutoGrowWdt= bTextFrame && IsAutoGrowWidth();
2010 
2011         if ((bGrowX && bAutoGrowWdt) || (bGrowY && bAutoGrowHgt))
2012         {
2013             AdjustTextFrameWidthAndHeight();
2014         }
2015     }
2016 }
2017 
2018 /** returns the currently active text. */
2019 SdrText* SdrTextObj::getActiveText() const
2020 {
2021     if( !mpText )
2022         return getText( 0 );
2023     else
2024         return mpText;
2025 }
2026 
2027 /** returns the nth available text. */
2028 SdrText* SdrTextObj::getText( sal_Int32 nIndex ) const
2029 {
2030     if( nIndex == 0 )
2031     {
2032         if( mpText == 0 )
2033             const_cast< SdrTextObj* >(this)->mpText = new SdrText( *(const_cast< SdrTextObj* >(this)) );
2034         return mpText;
2035     }
2036     else
2037     {
2038         return 0;
2039     }
2040 }
2041 
2042 /** returns the number of texts available for this object. */
2043 sal_Int32 SdrTextObj::getTextCount() const
2044 {
2045     return 1;
2046 }
2047 
2048 /** changes the current active text */
2049 void SdrTextObj::setActiveText( sal_Int32 /*nIndex*/ )
2050 {
2051 }
2052 
2053 /** returns the index of the text that contains the given point or -1 */
2054 sal_Int32 SdrTextObj::CheckTextHit(const Point& /*rPnt*/) const
2055 {
2056     return 0;
2057 }
2058 
2059 void SdrTextObj::SetObjectItemNoBroadcast(const SfxPoolItem& rItem)
2060 {
2061     static_cast< sdr::properties::TextProperties& >(GetProperties()).SetObjectItemNoBroadcast(rItem);
2062 }
2063 
2064 /////////////////////////////////////////////////////////////////////////////////////////////////
2065 //
2066 // Konzept des TextObjekts:
2067 // ~~~~~~~~~~~~~~~~~~~~~~~~
2068 // Attribute/Varianten:
2069 // - sal_Bool Textrahmen / beschriftetes Zeichenobjekt
2070 // - sal_Bool FontWork                 (wenn nicht Textrahmen und nicht ContourTextFrame)
2071 // - sal_Bool ContourTextFrame         (wenn nicht Textrahmen und nicht Fontwork)
2072 // - long Drehwinkel               (wenn nicht FontWork)
2073 // - long Textrahmenabstaende      (wenn nicht FontWork)
2074 // - sal_Bool FitToSize                (wenn nicht FontWork)
2075 // - sal_Bool AutoGrowingWidth/Height  (wenn nicht FitToSize und nicht FontWork)
2076 // - long Min/MaxFrameWidth/Height (wenn AutoGrowingWidth/Height)
2077 // - enum Horizontale Textverankerung Links,Mitte,Rechts,Block,Stretch(ni)
2078 // - enum Vertikale Textverankerung Oben,Mitte,Unten,Block,Stretch(ni)
2079 // - enum Laufschrift              (wenn nicht FontWork)
2080 //
2081 // Jedes abgeleitete Objekt ist entweder ein Textrahmen (bTextFrame=sal_True)
2082 // oder ein beschriftetes Zeichenobjekt (bTextFrame=sal_False).
2083 //
2084 // Defaultverankerung von Textrahmen:
2085 //   SDRTEXTHORZADJUST_BLOCK, SDRTEXTVERTADJUST_TOP
2086 //   = statische Pooldefaults
2087 // Defaultverankerung von beschrifteten Zeichenobjekten:
2088 //   SDRTEXTHORZADJUST_CENTER, SDRTEXTVERTADJUST_CENTER
2089 //   durch harte Attributierung von SdrAttrObj
2090 //
2091 // Jedes vom SdrTextObj abgeleitete Objekt muss ein "UnrotatedSnapRect"
2092 // (->TakeUnrotatedSnapRect()) liefern (Drehreferenz ist TopLeft dieses
2093 // Rechtecks (aGeo.nDrehWink)), welches die Grundlage der Textverankerung
2094 // bildet. Von diesem werden dann ringsum die Textrahmenabstaende abgezogen;
2095 // das Ergebnis ist der Ankerbereich (->TakeTextAnchorRect()). Innerhalb
2096 // dieses Bereichs wird dann in Abhaengigkeit von der horizontalen und
2097 // vertikalen Ausrichtung (SdrTextVertAdjust,SdrTextHorzAdjust) der Ankerpunkt
2098 // sowie der Ausgabebereich bestimmt. Bei beschrifteten Grafikobjekten kann
2099 // der Ausgabebereich durchaus groesser als der Ankerbereich werden, bei
2100 // Textrahmen ist er stets kleiner oder gleich (ausser bei negativen Textrahmen-
2101 // abstaenden).
2102 //
2103 // FitToSize hat Prioritaet vor Textverankerung und AutoGrowHeight/Width. Der
2104 // Ausgabebereich ist bei FitToSize immer genau der Ankerbereich. Weiterhin
2105 // gibt es bei FitToSize keinen automatischen Zeilenumbruch.
2106 //
2107 // ContourTextFrame:
2108 // - long Drehwinkel
2109 // - long Textrahmenabstaende         spaeter vielleicht
2110 // - sal_Bool FitToSize                   spaeter vielleicht
2111 // - sal_Bool AutoGrowingWidth/Height     viel spaeter vielleicht
2112 // - long Min/MaxFrameWidth/Height    viel spaeter vielleicht
2113 // - enum Horizontale Textverankerung spaeter vielleicht, erstmal Links, Absatz zentr.
2114 // - enum Vertikale Textverankerung   spaeter vielleicht, erstmal oben
2115 // - enum Laufschrift                 spaeter vielleicht (evtl. sogar mit korrektem Clipping)
2116 //
2117 // Bei Aenderungen zu beachten:
2118 // - Paint
2119 // - HitTest
2120 // - ConvertToPoly
2121 // - Edit
2122 // - Drucken,Speichern, Paint in Nachbarview waerend Edit
2123 // - ModelChanged (z.B. durch NachbarView oder Lineale) waerend Edit
2124 // - FillColorChanged waerend Edit
2125 // - uvm...
2126 //
2127 /////////////////////////////////////////////////////////////////////////////////////////////////
2128 
2129