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