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