merge the formfield patch from ooo-build
[ooovba.git] / svx / source / svdraw / svdotext.cxx
blobf92dba5027a74fba35c4782dd196450bb1b93e90
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdotext.cxx,v $
10 * $Revision: 1.90.40.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <svx/svdotext.hxx>
35 #include "svditext.hxx"
36 #include <svx/svdpagv.hxx> // fuer Abfrage im Paint, ob das
37 #include <svx/svdview.hxx> // Objekt gerade editiert wird
38 #include <svx/svdpage.hxx> // und fuer AnimationHandler (Laufschrift)
39 #include <svx/svdetc.hxx>
40 #include <svx/svdoutl.hxx>
41 #include "svdscrol.hxx" // fuer Laufschrift
42 #include <svx/svdmodel.hxx> // OutlinerDefaults
43 #include "svdglob.hxx" // Stringcache
44 #include "svdstr.hrc" // Objektname
45 #include <svx/writingmodeitem.hxx>
46 #include <svx/sdtfchim.hxx>
47 #include <svtools/colorcfg.hxx>
48 #include <svx/eeitem.hxx>
49 #include <editstat.hxx>
50 #include <svx/outlobj.hxx>
51 #include <svx/editobj.hxx>
52 #include <svx/outliner.hxx>
53 #include <svx/fhgtitem.hxx>
54 #include <svtools/itempool.hxx>
55 #include <svx/adjitem.hxx>
56 #include <svx/flditem.hxx>
57 #include <svx/xftouit.hxx>
58 #include <vcl/salbtype.hxx> // FRound
59 #include <svx/xflgrit.hxx>
60 #include <svx/svdpool.hxx>
61 #include <svx/xflclit.hxx>
62 #include <svtools/style.hxx>
63 #include <svx/editeng.hxx>
64 #include <svtools/itemiter.hxx>
65 #include <svx/sdr/properties/textproperties.hxx>
67 // #110496#
68 #include <vcl/metaact.hxx>
70 // #111111#
71 #include <svx/sdr/contact/viewcontactoftextobj.hxx>
72 #include <basegfx/tuple/b2dtuple.hxx>
73 #include <basegfx/matrix/b2dhommatrix.hxx>
74 #include <basegfx/polygon/b2dpolygon.hxx>
75 #include <drawinglayer/geometry/viewinformation2d.hxx>
76 #include <vcl/virdev.hxx>
78 //////////////////////////////////////////////////////////////////////////////
80 using namespace com::sun::star;
82 //////////////////////////////////////////////////////////////////////////////
83 // #104018# replace macros above with type-safe methods
84 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
85 inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
87 ////////////////////////////////////////////////////////////////////////////////////////////////////
89 // @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
90 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
91 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
92 // @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
93 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
94 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
95 // @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
97 ////////////////////////////////////////////////////////////////////////////////////////////////////
99 //////////////////////////////////////////////////////////////////////////////
100 // BaseProperties section
102 sdr::properties::BaseProperties* SdrTextObj::CreateObjectSpecificProperties()
104 return new sdr::properties::TextProperties(*this);
107 //////////////////////////////////////////////////////////////////////////////
108 // DrawContact section
110 sdr::contact::ViewContact* SdrTextObj::CreateObjectSpecificViewContact()
112 return new sdr::contact::ViewContactOfTextObj(*this);
115 //////////////////////////////////////////////////////////////////////////////
117 TYPEINIT1(SdrTextObj,SdrAttrObj);
119 SdrTextObj::SdrTextObj()
120 : SdrAttrObj(),
121 mpText(NULL),
122 pEdtOutl(NULL),
123 pFormTextBoundRect(NULL),
124 eTextKind(OBJ_TEXT)
126 bTextSizeDirty=FALSE;
127 bTextFrame=FALSE;
128 bNoShear=FALSE;
129 bNoRotate=FALSE;
130 bNoMirror=FALSE;
131 bDisableAutoWidthOnDragging=FALSE;
133 // #101684#
134 mbInEditMode = FALSE;
136 // #111096#
137 mbTextHidden = sal_False;
139 // #111096#
140 mbTextAnimationAllowed = sal_True;
142 // #108784#
143 maTextEditOffset = Point(0, 0);
145 // #i25616#
146 mbSupportTextIndentingOnLineWidthChange = sal_True;
147 mbInDownScale = sal_False;
150 SdrTextObj::SdrTextObj(const Rectangle& rNewRect)
151 : SdrAttrObj(),
152 aRect(rNewRect),
153 mpText(NULL),
154 pEdtOutl(NULL),
155 pFormTextBoundRect(NULL)
157 bTextSizeDirty=FALSE;
158 bTextFrame=FALSE;
159 bNoShear=FALSE;
160 bNoRotate=FALSE;
161 bNoMirror=FALSE;
162 bDisableAutoWidthOnDragging=FALSE;
163 ImpJustifyRect(aRect);
165 // #101684#
166 mbInEditMode = FALSE;
168 // #111096#
169 mbTextHidden = sal_False;
171 // #111096#
172 mbTextAnimationAllowed = sal_True;
173 mbInDownScale = sal_False;
175 // #108784#
176 maTextEditOffset = Point(0, 0);
178 // #i25616#
179 mbSupportTextIndentingOnLineWidthChange = sal_True;
182 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind)
183 : SdrAttrObj(),
184 mpText(NULL),
185 pEdtOutl(NULL),
186 pFormTextBoundRect(NULL),
187 eTextKind(eNewTextKind)
189 bTextSizeDirty=FALSE;
190 bTextFrame=TRUE;
191 bNoShear=TRUE;
192 bNoRotate=FALSE;
193 bNoMirror=TRUE;
194 bDisableAutoWidthOnDragging=FALSE;
196 // #101684#
197 mbInEditMode = FALSE;
199 // #111096#
200 mbTextHidden = sal_False;
202 // #111096#
203 mbTextAnimationAllowed = sal_True;
204 mbInDownScale = sal_False;
206 // #108784#
207 maTextEditOffset = Point(0, 0);
209 // #i25616#
210 mbSupportTextIndentingOnLineWidthChange = sal_True;
213 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect)
214 : SdrAttrObj(),
215 aRect(rNewRect),
216 mpText(NULL),
217 pEdtOutl(NULL),
218 pFormTextBoundRect(NULL),
219 eTextKind(eNewTextKind)
221 bTextSizeDirty=FALSE;
222 bTextFrame=TRUE;
223 bNoShear=TRUE;
224 bNoRotate=FALSE;
225 bNoMirror=TRUE;
226 bDisableAutoWidthOnDragging=FALSE;
227 ImpJustifyRect(aRect);
229 // #101684#
230 mbInEditMode = FALSE;
232 // #111096#
233 mbTextHidden = sal_False;
235 // #111096#
236 mbTextAnimationAllowed = sal_True;
237 mbInDownScale = sal_False;
239 // #108784#
240 maTextEditOffset = Point(0, 0);
242 // #i25616#
243 mbSupportTextIndentingOnLineWidthChange = sal_True;
246 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect, SvStream& rInput, const String& rBaseURL, USHORT eFormat)
247 : SdrAttrObj(),
248 aRect(rNewRect),
249 mpText(NULL),
250 pEdtOutl(NULL),
251 pFormTextBoundRect(NULL),
252 eTextKind(eNewTextKind)
254 bTextSizeDirty=FALSE;
255 bTextFrame=TRUE;
256 bNoShear=TRUE;
257 bNoRotate=FALSE;
258 bNoMirror=TRUE;
259 bDisableAutoWidthOnDragging=FALSE;
260 ImpJustifyRect(aRect);
262 NbcSetText(rInput, rBaseURL, eFormat);
264 // #101684#
265 mbInEditMode = FALSE;
267 // #111096#
268 mbTextHidden = sal_False;
270 // #111096#
271 mbTextAnimationAllowed = sal_True;
272 mbInDownScale = sal_False;
274 // #108784#
275 maTextEditOffset = Point(0, 0);
277 // #i25616#
278 mbSupportTextIndentingOnLineWidthChange = sal_True;
281 SdrTextObj::~SdrTextObj()
283 if( pModel )
285 SdrOutliner& rOutl = pModel->GetHitTestOutliner();
286 if( rOutl.GetTextObj() == this )
287 rOutl.SetTextObj( NULL );
290 if(mpText!=NULL)
291 delete mpText;
293 if (pFormTextBoundRect!=NULL)
294 delete pFormTextBoundRect;
296 ImpLinkAbmeldung();
299 void SdrTextObj::FitFrameToTextSize()
301 DBG_ASSERT(pModel!=NULL,"SdrTextObj::FitFrameToTextSize(): pModel=NULL!");
302 ImpJustifyRect(aRect);
304 SdrText* pText = getActiveText();
305 if( pText!=NULL && pText->GetOutlinerParaObject() && pModel!=NULL)
307 SdrOutliner& rOutliner=ImpGetDrawOutliner();
308 rOutliner.SetPaperSize(Size(aRect.Right()-aRect.Left(),aRect.Bottom()-aRect.Top()));
309 rOutliner.SetUpdateMode(TRUE);
310 rOutliner.SetText(*pText->GetOutlinerParaObject());
311 Rectangle aTextRect;
312 Size aNewSize(rOutliner.CalcTextSize());
313 rOutliner.Clear();
314 aNewSize.Width()++; // wegen evtl. Rundungsfehler
315 aNewSize.Width()+=GetTextLeftDistance()+GetTextRightDistance();
316 aNewSize.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
317 Rectangle aNewRect(aRect);
318 aNewRect.SetSize(aNewSize);
319 ImpJustifyRect(aNewRect);
320 if (aNewRect!=aRect) {
321 SetLogicRect(aNewRect);
326 void SdrTextObj::NbcSetText(const XubString& rStr)
328 SdrOutliner& rOutliner=ImpGetDrawOutliner();
329 rOutliner.SetStyleSheet( 0, GetStyleSheet());
330 //OutputDevice* pRef1=rOutliner.GetRefDevice();
331 rOutliner.SetUpdateMode(TRUE);
332 rOutliner.SetText(rStr,rOutliner.GetParagraph( 0 ));
333 OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
334 Size aSiz(rOutliner.CalcTextSize());
335 //OutputDevice* pRef2=rOutliner.GetRefDevice();
336 rOutliner.Clear();
337 NbcSetOutlinerParaObject(pNewText);
338 aTextSize=aSiz;
339 bTextSizeDirty=FALSE;
342 void SdrTextObj::SetText(const XubString& rStr)
344 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
345 // #110094#-14 SendRepaintBroadcast();
346 NbcSetText(rStr);
347 SetChanged();
348 BroadcastObjectChange();
349 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
350 //if (GetBoundRect()!=aBoundRect0) {
351 // SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
355 void SdrTextObj::NbcSetText(SvStream& rInput, const String& rBaseURL, USHORT eFormat)
357 SdrOutliner& rOutliner=ImpGetDrawOutliner();
358 rOutliner.SetStyleSheet( 0, GetStyleSheet());
359 rOutliner.Read(rInput,rBaseURL,eFormat);
360 OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
361 rOutliner.SetUpdateMode(TRUE);
362 Size aSiz(rOutliner.CalcTextSize());
363 rOutliner.Clear();
364 NbcSetOutlinerParaObject(pNewText);
365 aTextSize=aSiz;
366 bTextSizeDirty=FALSE;
369 void SdrTextObj::SetText(SvStream& rInput, const String& rBaseURL, USHORT eFormat)
371 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
372 // #110094#-14 SendRepaintBroadcast();
373 NbcSetText(rInput,rBaseURL,eFormat);
374 SetChanged();
375 BroadcastObjectChange();
376 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
379 const Size& SdrTextObj::GetTextSize() const
381 if (bTextSizeDirty)
383 Size aSiz;
384 SdrText* pText = getActiveText();
385 if( pText && pText->GetOutlinerParaObject ())
387 SdrOutliner& rOutliner=ImpGetDrawOutliner();
388 rOutliner.SetText(*pText->GetOutlinerParaObject());
389 rOutliner.SetUpdateMode(TRUE);
390 aSiz=rOutliner.CalcTextSize();
391 rOutliner.Clear();
393 // 2x casting auf nonconst
394 ((SdrTextObj*)this)->aTextSize=aSiz;
395 ((SdrTextObj*)this)->bTextSizeDirty=FALSE;
397 return aTextSize;
400 FASTBOOL SdrTextObj::IsAutoGrowHeight() const
402 if(!bTextFrame)
403 return FALSE; // AutoGrow nur bei TextFrames
405 const SfxItemSet& rSet = GetObjectItemSet();
406 BOOL bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
408 if(bRet)
410 SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
412 if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
414 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
416 if(eDirection == SDRTEXTANI_UP || eDirection == SDRTEXTANI_DOWN)
418 bRet = FALSE;
422 return bRet;
425 FASTBOOL SdrTextObj::IsAutoGrowWidth() const
427 if(!bTextFrame)
428 return FALSE; // AutoGrow nur bei TextFrames
430 const SfxItemSet& rSet = GetObjectItemSet();
431 BOOL bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue();
433 // #101684#
434 BOOL bInEditMOde = IsInEditMode();
436 if(!bInEditMOde && bRet)
438 SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
440 if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
442 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
444 if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
446 bRet = FALSE;
450 return bRet;
453 SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust() const
455 return GetTextHorizontalAdjust(GetObjectItemSet());
458 SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust(const SfxItemSet& rSet) const
460 if(IsContourTextFrame())
461 return SDRTEXTHORZADJUST_BLOCK;
463 SdrTextHorzAdjust eRet = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
465 // #101684#
466 BOOL bInEditMode = IsInEditMode();
468 if(!bInEditMode && eRet == SDRTEXTHORZADJUST_BLOCK)
470 SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
472 if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
474 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
476 if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
478 eRet = SDRTEXTHORZADJUST_LEFT;
483 return eRet;
484 } // defaults: BLOCK fuer Textrahmen, CENTER fuer beschriftete Grafikobjekte
486 SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust() const
488 return GetTextVerticalAdjust(GetObjectItemSet());
491 SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust(const SfxItemSet& rSet) const
493 if(IsContourTextFrame())
494 return SDRTEXTVERTADJUST_TOP;
496 // #103516# Take care for vertical text animation here
497 SdrTextVertAdjust eRet = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
498 BOOL bInEditMode = IsInEditMode();
500 // #103516# Take care for vertical text animation here
501 if(!bInEditMode && eRet == SDRTEXTVERTADJUST_BLOCK)
503 SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
505 if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
507 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
509 if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
511 eRet = SDRTEXTVERTADJUST_TOP;
516 return eRet;
517 } // defaults: TOP fuer Textrahmen, CENTER fuer beschriftete Grafikobjekte
519 void SdrTextObj::ImpJustifyRect(Rectangle& rRect) const
521 if (!rRect.IsEmpty()) {
522 rRect.Justify();
523 if (rRect.Left()==rRect.Right()) rRect.Right()++;
524 if (rRect.Top()==rRect.Bottom()) rRect.Bottom()++;
528 void SdrTextObj::ImpCheckShear()
530 if (bNoShear && aGeo.nShearWink!=0) {
531 aGeo.nShearWink=0;
532 aGeo.nTan=0;
536 void SdrTextObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
538 FASTBOOL bNoTextFrame=!IsTextFrame();
539 rInfo.bResizeFreeAllowed=bNoTextFrame || aGeo.nDrehWink%9000==0;
540 rInfo.bResizePropAllowed=TRUE;
541 rInfo.bRotateFreeAllowed=TRUE;
542 rInfo.bRotate90Allowed =TRUE;
543 rInfo.bMirrorFreeAllowed=bNoTextFrame;
544 rInfo.bMirror45Allowed =bNoTextFrame;
545 rInfo.bMirror90Allowed =bNoTextFrame;
547 // allow transparence
548 rInfo.bTransparenceAllowed = TRUE;
550 // gradient depends on fillstyle
551 XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
552 rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
553 rInfo.bShearAllowed =bNoTextFrame;
554 rInfo.bEdgeRadiusAllowed=TRUE;
555 FASTBOOL bCanConv=ImpCanConvTextToCurve();
556 rInfo.bCanConvToPath =bCanConv;
557 rInfo.bCanConvToPoly =bCanConv;
558 rInfo.bCanConvToPathLineToArea=bCanConv;
559 rInfo.bCanConvToPolyLineToArea=bCanConv;
560 rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
563 UINT16 SdrTextObj::GetObjIdentifier() const
565 return USHORT(eTextKind);
568 bool SdrTextObj::HasTextImpl( SdrOutliner* pOutliner )
570 bool bRet=false;
571 if(pOutliner)
573 Paragraph* p1stPara=pOutliner->GetParagraph( 0 );
574 ULONG nParaAnz=pOutliner->GetParagraphCount();
575 if(p1stPara==NULL)
576 nParaAnz=0;
578 if(nParaAnz==1)
580 // if it is only one paragraph, check if that paragraph is empty
581 XubString aStr(pOutliner->GetText(p1stPara));
583 if(!aStr.Len())
584 nParaAnz = 0;
587 bRet= nParaAnz!=0;
589 return bRet;
592 FASTBOOL SdrTextObj::HasEditText() const
594 return HasTextImpl( pEdtOutl );
597 void SdrTextObj::SetPage(SdrPage* pNewPage)
599 FASTBOOL bRemove=pNewPage==NULL && pPage!=NULL;
600 FASTBOOL bInsert=pNewPage!=NULL && pPage==NULL;
601 FASTBOOL bLinked=IsLinkedText();
603 if (bLinked && bRemove) {
604 ImpLinkAbmeldung();
607 SdrAttrObj::SetPage(pNewPage);
609 if (bLinked && bInsert) {
610 ImpLinkAnmeldung();
614 void SdrTextObj::SetModel(SdrModel* pNewModel)
616 SdrModel* pOldModel=pModel;
617 bool bLinked=IsLinkedText();
618 bool bChg=pNewModel!=pModel;
620 if (bLinked && bChg)
622 ImpLinkAbmeldung();
625 SdrAttrObj::SetModel(pNewModel);
627 if( bChg )
629 if( pNewModel != 0 && pOldModel != 0 )
630 SetTextSizeDirty();
632 sal_Int32 nCount = getTextCount();
633 for( sal_Int32 nText = 0; nText < nCount; nText++ )
635 SdrText* pText = getText( nText );
636 if( pText )
637 pText->SetModel( pNewModel );
641 if (bLinked && bChg)
643 ImpLinkAnmeldung();
647 FASTBOOL SdrTextObj::NbcSetEckenradius(long nRad)
649 SetObjectItem(SdrEckenradiusItem(nRad));
650 return TRUE;
653 FASTBOOL SdrTextObj::NbcSetAutoGrowHeight(bool bAuto)
655 if(bTextFrame)
657 SetObjectItem(SdrTextAutoGrowHeightItem(bAuto));
658 return TRUE;
660 return FALSE;
663 FASTBOOL SdrTextObj::NbcSetMinTextFrameHeight(long nHgt)
665 if( bTextFrame && ( !pModel || !pModel->isLocked() ) ) // SJ: #i44922#
667 SetObjectItem(SdrTextMinFrameHeightItem(nHgt));
669 // #84974# use bDisableAutoWidthOnDragging as
670 // bDisableAutoHeightOnDragging if vertical.
671 if(IsVerticalWriting() && bDisableAutoWidthOnDragging)
673 bDisableAutoWidthOnDragging = FALSE;
674 SetObjectItem(SdrTextAutoGrowHeightItem(FALSE));
677 return TRUE;
679 return FALSE;
682 FASTBOOL SdrTextObj::NbcSetMaxTextFrameHeight(long nHgt)
684 if(bTextFrame)
686 SetObjectItem(SdrTextMaxFrameHeightItem(nHgt));
687 return TRUE;
689 return FALSE;
692 FASTBOOL SdrTextObj::NbcSetAutoGrowWidth(bool bAuto)
694 if(bTextFrame)
696 SetObjectItem(SdrTextAutoGrowWidthItem(bAuto));
697 return TRUE;
699 return FALSE;
702 FASTBOOL SdrTextObj::NbcSetMinTextFrameWidth(long nWdt)
704 if( bTextFrame && ( !pModel || !pModel->isLocked() ) ) // SJ: #i44922#
706 SetObjectItem(SdrTextMinFrameWidthItem(nWdt));
708 // #84974# use bDisableAutoWidthOnDragging only
709 // when not vertical.
710 if(!IsVerticalWriting() && bDisableAutoWidthOnDragging)
712 bDisableAutoWidthOnDragging = FALSE;
713 SetObjectItem(SdrTextAutoGrowWidthItem(FALSE));
716 return TRUE;
718 return FALSE;
721 FASTBOOL SdrTextObj::NbcSetMaxTextFrameWidth(long nWdt)
723 if(bTextFrame)
725 SetObjectItem(SdrTextMaxFrameWidthItem(nWdt));
726 return TRUE;
728 return FALSE;
731 FASTBOOL SdrTextObj::NbcSetFitToSize(SdrFitToSizeType eFit)
733 if(bTextFrame)
735 SetObjectItem(SdrTextFitToSizeTypeItem(eFit));
736 return TRUE;
738 return FALSE;
741 void SdrTextObj::ImpSetContourPolygon( SdrOutliner& rOutliner, Rectangle& rAnchorRect, BOOL bLineWidth ) const
743 basegfx::B2DPolyPolygon aXorPolyPolygon(TakeXorPoly());
744 basegfx::B2DPolyPolygon* pContourPolyPolygon = 0L;
745 basegfx::B2DHomMatrix aMatrix;
747 aMatrix.translate(-rAnchorRect.Left(), -rAnchorRect.Top());
748 if(aGeo.nDrehWink)
750 // Unrotate!
751 aMatrix.rotate(-aGeo.nDrehWink * nPi180);
754 aXorPolyPolygon.transform(aMatrix);
756 if( bLineWidth )
758 // Strichstaerke beruecksichtigen
759 // Beim Hittest muss das unterbleiben (Performance!)
760 pContourPolyPolygon = new basegfx::B2DPolyPolygon();
762 // #86258# test if shadow needs to be avoided for TakeContour()
763 const SfxItemSet& rSet = GetObjectItemSet();
764 sal_Bool bShadowOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
766 // #i33696#
767 // Remember TextObject currently set at the DrawOutliner, it WILL be
768 // replaced during calculating the outline since it uses an own paint
769 // and that one uses the DrawOutliner, too.
770 const SdrTextObj* pLastTextObject = rOutliner.GetTextObj();
772 if(bShadowOn)
774 // #86258# force shadow off
775 SdrObject* pCopy = Clone();
776 pCopy->SetMergedItem(SdrShadowItem(FALSE));
777 *pContourPolyPolygon = pCopy->TakeContour();
778 SdrObject::Free( pCopy );
780 else
782 *pContourPolyPolygon = TakeContour();
785 // #i33696#
786 // restore remembered text object
787 if(pLastTextObject != rOutliner.GetTextObj())
789 rOutliner.SetTextObj(pLastTextObject);
792 pContourPolyPolygon->transform(aMatrix);
795 rOutliner.SetPolygon(aXorPolyPolygon, pContourPolyPolygon);
798 void SdrTextObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
800 rRect=aRect;
803 void SdrTextObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
805 long nLeftDist=GetTextLeftDistance();
806 long nRightDist=GetTextRightDistance();
807 long nUpperDist=GetTextUpperDistance();
808 long nLowerDist=GetTextLowerDistance();
809 Rectangle aAnkRect(aRect); // Rect innerhalb dem geankert wird
810 FASTBOOL bFrame=IsTextFrame();
811 if (!bFrame) {
812 TakeUnrotatedSnapRect(aAnkRect);
814 Point aRotateRef(aAnkRect.TopLeft());
815 aAnkRect.Left()+=nLeftDist;
816 aAnkRect.Top()+=nUpperDist;
817 aAnkRect.Right()-=nRightDist;
818 aAnkRect.Bottom()-=nLowerDist;
820 // #108816#
821 // Since sizes may be bigger than the object bounds it is necessary to
822 // justify the rect now.
823 ImpJustifyRect(aAnkRect);
825 if (bFrame) {
826 // !!! hier noch etwas verfeinern !!!
827 if (aAnkRect.GetWidth()<2) aAnkRect.Right()=aAnkRect.Left()+1; // Mindestgroesse 2
828 if (aAnkRect.GetHeight()<2) aAnkRect.Bottom()=aAnkRect.Top()+1; // Mindestgroesse 2
830 if (aGeo.nDrehWink!=0) {
831 Point aTmpPt(aAnkRect.TopLeft());
832 RotatePoint(aTmpPt,aRotateRef,aGeo.nSin,aGeo.nCos);
833 aTmpPt-=aAnkRect.TopLeft();
834 aAnkRect.Move(aTmpPt.X(),aTmpPt.Y());
836 rAnchorRect=aAnkRect;
839 void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
840 Rectangle* pAnchorRect, BOOL bLineWidth ) const
842 Rectangle aAnkRect; // Rect innerhalb dem geankert wird
843 TakeTextAnchorRect(aAnkRect);
844 SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
845 SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
846 SdrTextAniKind eAniKind=GetTextAniKind();
847 SdrTextAniDirection eAniDirection=GetTextAniDirection();
849 FASTBOOL bFitToSize(IsFitToSize());
850 FASTBOOL bContourFrame=IsContourTextFrame();
852 FASTBOOL bFrame=IsTextFrame();
853 ULONG nStat0=rOutliner.GetControlWord();
854 Size aNullSize;
855 if (!bContourFrame)
857 rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
858 rOutliner.SetMinAutoPaperSize(aNullSize);
859 rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
862 if (!bFitToSize && !bContourFrame)
864 long nAnkWdt=aAnkRect.GetWidth();
865 long nAnkHgt=aAnkRect.GetHeight();
866 if (bFrame)
868 long nWdt=nAnkWdt;
869 long nHgt=nAnkHgt;
871 // #101684#
872 BOOL bInEditMode = IsInEditMode();
874 if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
876 // Grenzenlose Papiergroesse fuer Laufschrift
877 if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nWdt=1000000;
878 if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nHgt=1000000;
880 rOutliner.SetMaxAutoPaperSize(Size(nWdt,nHgt));
883 // #103516# New try with _BLOCK for hor and ver after completely
884 // supporting full width for vertical text.
885 if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
887 rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
890 if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
892 rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
896 rOutliner.SetPaperSize(aNullSize);
897 if (bContourFrame)
898 ImpSetContourPolygon( rOutliner, aAnkRect, bLineWidth );
900 // put text into the outliner, if available from the edit outliner
901 SdrText* pText = getActiveText();
902 OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
903 OutlinerParaObject* pPara = (pEdtOutl && !bNoEditText) ? pEdtOutl->CreateParaObject() : pOutlinerParaObject;
905 if (pPara)
907 BOOL bHitTest = FALSE;
908 if( pModel )
909 bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
911 const SdrTextObj* pTestObj = rOutliner.GetTextObj();
912 if( !pTestObj || !bHitTest || pTestObj != this ||
913 pTestObj->GetOutlinerParaObject() != pOutlinerParaObject )
915 if( bHitTest ) // #i33696# take back fix #i27510#
917 rOutliner.SetTextObj( this );
918 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
921 rOutliner.SetUpdateMode(TRUE);
922 rOutliner.SetText(*pPara);
925 else
927 rOutliner.SetTextObj( NULL );
930 if (pEdtOutl && !bNoEditText && pPara)
931 delete pPara;
933 rOutliner.SetUpdateMode(TRUE);
934 rOutliner.SetControlWord(nStat0);
936 if( pText )
937 pText->CheckPortionInfo(rOutliner);
939 Point aTextPos(aAnkRect.TopLeft());
940 Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder?
942 // #106653#
943 // For draw objects containing text correct hor/ver alignment if text is bigger
944 // than the object itself. Without that correction, the text would always be
945 // formatted to the left edge (or top edge when vertical) of the draw object.
946 if(!IsTextFrame())
948 if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
950 // #110129#
951 // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
952 // else the alignment is wanted.
953 if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
955 eHAdj = SDRTEXTHORZADJUST_CENTER;
959 if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
961 // #110129#
962 // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
963 // else the alignment is wanted.
964 if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
966 eVAdj = SDRTEXTVERTADJUST_CENTER;
971 if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
973 long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
974 if (eHAdj==SDRTEXTHORZADJUST_CENTER)
975 aTextPos.X()+=nFreeWdt/2;
976 if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
977 aTextPos.X()+=nFreeWdt;
979 if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
981 long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
982 if (eVAdj==SDRTEXTVERTADJUST_CENTER)
983 aTextPos.Y()+=nFreeHgt/2;
984 if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
985 aTextPos.Y()+=nFreeHgt;
987 if (aGeo.nDrehWink!=0)
988 RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
990 if (pAnchorRect)
991 *pAnchorRect=aAnkRect;
993 // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt
994 rTextRect=Rectangle(aTextPos,aTextSiz);
995 if (bContourFrame)
996 rTextRect=aAnkRect;
999 OutlinerParaObject* SdrTextObj::GetEditOutlinerParaObject() const
1001 OutlinerParaObject* pPara=NULL;
1002 if( HasTextImpl( pEdtOutl ) )
1004 sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( pEdtOutl->GetParagraphCount() );
1005 pPara = pEdtOutl->CreateParaObject(0, nParaAnz);
1007 return pPara;
1010 void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Size& rTextSize, const Size& rShapeSize, Fraction& rFitXKorreg) const
1012 OutputDevice* pOut = rOutliner.GetRefDevice();
1013 BOOL bNoStretching(FALSE);
1015 if(pOut && pOut->GetOutDevType() == OUTDEV_PRINTER)
1017 // #35762#: Checken ob CharStretching ueberhaupt moeglich
1018 GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
1019 UniString aTestString(sal_Unicode('J'));
1021 if(pMtf && (!pMtf->IsRecord() || pMtf->IsPause()))
1022 pMtf = NULL;
1024 if(pMtf)
1025 pMtf->Pause(TRUE);
1027 Font aFontMerk(pOut->GetFont());
1028 Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ) );
1030 aTmpFont.SetSize(Size(0,100));
1031 pOut->SetFont(aTmpFont);
1032 Size aSize1(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
1033 aTmpFont.SetSize(Size(800,100));
1034 pOut->SetFont(aTmpFont);
1035 Size aSize2(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
1036 pOut->SetFont(aFontMerk);
1038 if(pMtf)
1039 pMtf->Pause(FALSE);
1041 bNoStretching = (aSize1 == aSize2);
1043 #ifdef WNT
1044 // #35762# Windows vergroessert bei Size(100,500) den Font proportional
1045 // Und das finden wir nicht so schoen.
1046 if(aSize2.Height() >= aSize1.Height() * 2)
1048 bNoStretching = TRUE;
1050 #endif
1052 unsigned nLoopCount=0;
1053 FASTBOOL bNoMoreLoop=FALSE;
1054 long nXDiff0=0x7FFFFFFF;
1055 long nWantWdt=rShapeSize.Width();
1056 long nIsWdt=rTextSize.Width();
1057 if (nIsWdt==0) nIsWdt=1;
1059 long nWantHgt=rShapeSize.Height();
1060 long nIsHgt=rTextSize.Height();
1061 if (nIsHgt==0) nIsHgt=1;
1063 long nXTolPl=nWantWdt/100; // Toleranz +1%
1064 long nXTolMi=nWantWdt/25; // Toleranz -4%
1065 long nXKorr =nWantWdt/20; // Korrekturmasstab 5%
1067 long nX=(nWantWdt*100) /nIsWdt; // X-Stretching berechnen
1068 long nY=(nWantHgt*100) /nIsHgt; // Y-Stretching berechnen
1069 FASTBOOL bChkX=TRUE;
1070 FASTBOOL bChkY=TRUE;
1071 if (bNoStretching) { // #35762# evtl. nur proportional moeglich
1072 if (nX>nY) { nX=nY; bChkX=FALSE; }
1073 else { nY=nX; bChkY=FALSE; }
1076 while (nLoopCount<5 && !bNoMoreLoop) {
1077 if (nX<0) nX=-nX;
1078 if (nX<1) { nX=1; bNoMoreLoop=TRUE; }
1079 if (nX>65535) { nX=65535; bNoMoreLoop=TRUE; }
1081 if (nY<0) nY=-nY;
1082 if (nY<1) { nY=1; bNoMoreLoop=TRUE; }
1083 if (nY>65535) { nY=65535; bNoMoreLoop=TRUE; }
1085 // exception, there is no text yet (horizontal case)
1086 if(nIsWdt <= 1)
1088 nX = nY;
1089 bNoMoreLoop = TRUE;
1092 // #87877# exception, there is no text yet (vertical case)
1093 if(nIsHgt <= 1)
1095 nY = nX;
1096 bNoMoreLoop = TRUE;
1099 rOutliner.SetGlobalCharStretching((USHORT)nX,(USHORT)nY);
1100 nLoopCount++;
1101 Size aSiz(rOutliner.CalcTextSize());
1102 long nXDiff=aSiz.Width()-nWantWdt;
1103 rFitXKorreg=Fraction(nWantWdt,aSiz.Width());
1104 if (((nXDiff>=nXTolMi || !bChkX) && nXDiff<=nXTolPl) || nXDiff==nXDiff0/*&& Abs(nYDiff)<=nYTol*/) {
1105 bNoMoreLoop=TRUE;
1106 } else {
1107 // Stretchingfaktoren korregieren
1108 long nMul=nWantWdt;
1109 long nDiv=aSiz.Width();
1110 if (Abs(nXDiff)<=2*nXKorr) {
1111 if (nMul>nDiv) nDiv+=(nMul-nDiv)/2; // und zwar nur um die haelfte des berechneten
1112 else nMul+=(nDiv-nMul)/2; // weil die EE ja eh wieder falsch rechnet
1114 nX=nX*nMul/nDiv;
1115 if (bNoStretching) nY=nX;
1117 nXDiff0=nXDiff;
1121 void SdrTextObj::StartTextAnimation(OutputDevice* /*pOutDev*/, const Point& /*rOffset*/, long /*nExtraData*/)
1123 // #111096#
1124 // use new text animation
1125 SetTextAnimationAllowed(sal_True);
1128 void SdrTextObj::StopTextAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
1130 // #111096#
1131 // use new text animation
1132 SetTextAnimationAllowed(sal_False);
1135 void SdrTextObj::TakeObjNameSingul(XubString& rName) const
1137 XubString aStr;
1139 switch(eTextKind)
1141 case OBJ_OUTLINETEXT:
1143 aStr = ImpGetResStr(STR_ObjNameSingulOUTLINETEXT);
1144 break;
1147 case OBJ_TITLETEXT :
1149 aStr = ImpGetResStr(STR_ObjNameSingulTITLETEXT);
1150 break;
1153 default:
1155 if(IsLinkedText())
1156 aStr = ImpGetResStr(STR_ObjNameSingulTEXTLNK);
1157 else
1158 aStr = ImpGetResStr(STR_ObjNameSingulTEXT);
1159 break;
1163 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1164 if(pOutlinerParaObject && eTextKind != OBJ_OUTLINETEXT)
1166 // Macht bei OUTLINETEXT wohl derzeit noch etwas Probleme
1167 XubString aStr2(pOutlinerParaObject->GetTextObject().GetText(0));
1168 aStr2.EraseLeadingChars();
1170 // #69446# avoid non expanded text portions in object name
1171 // (second condition is new)
1172 if(aStr2.Len() && aStr2.Search(sal_Unicode(255)) == STRING_NOTFOUND)
1174 // #76681# space between ResStr and content text
1175 aStr += sal_Unicode(' ');
1177 aStr += sal_Unicode('\'');
1179 if(aStr2.Len() > 10)
1181 aStr2.Erase(8);
1182 aStr2.AppendAscii("...", 3);
1185 aStr += aStr2;
1186 aStr += sal_Unicode('\'');
1190 rName = aStr;
1192 String aName( GetName() );
1193 if(aName.Len())
1195 rName += sal_Unicode(' ');
1196 rName += sal_Unicode('\'');
1197 rName += aName;
1198 rName += sal_Unicode('\'');
1203 void SdrTextObj::TakeObjNamePlural(XubString& rName) const
1205 switch (eTextKind) {
1206 case OBJ_OUTLINETEXT: rName=ImpGetResStr(STR_ObjNamePluralOUTLINETEXT); break;
1207 case OBJ_TITLETEXT : rName=ImpGetResStr(STR_ObjNamePluralTITLETEXT); break;
1208 default: {
1209 if (IsLinkedText()) {
1210 rName=ImpGetResStr(STR_ObjNamePluralTEXTLNK);
1211 } else {
1212 rName=ImpGetResStr(STR_ObjNamePluralTEXT);
1214 } break;
1215 } // switch
1218 void SdrTextObj::operator=(const SdrObject& rObj)
1220 // call parent
1221 SdrObject::operator=(rObj);
1223 const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >( &rObj );
1224 if (pTextObj!=NULL)
1226 aRect =pTextObj->aRect;
1227 aGeo =pTextObj->aGeo;
1228 eTextKind =pTextObj->eTextKind;
1229 bTextFrame=pTextObj->bTextFrame;
1230 aTextSize=pTextObj->aTextSize;
1231 bTextSizeDirty=pTextObj->bTextSizeDirty;
1233 // #101776# Not all of the necessary parameters were copied yet.
1234 bNoShear = pTextObj->bNoShear;
1235 bNoRotate = pTextObj->bNoRotate;
1236 bNoMirror = pTextObj->bNoMirror;
1237 bDisableAutoWidthOnDragging = pTextObj->bDisableAutoWidthOnDragging;
1239 OutlinerParaObject* pNewOutlinerParaObject = 0;
1241 SdrText* pText = getActiveText();
1243 if( pText && pTextObj->HasText() )
1245 const Outliner* pEO=pTextObj->pEdtOutl;
1246 if (pEO!=NULL)
1248 pNewOutlinerParaObject = pEO->CreateParaObject();
1250 else
1252 pNewOutlinerParaObject = new OutlinerParaObject(*pTextObj->getActiveText()->GetOutlinerParaObject());
1256 mpText->SetOutlinerParaObject( pNewOutlinerParaObject );
1257 ImpSetTextStyleSheetListeners();
1261 basegfx::B2DPolyPolygon SdrTextObj::TakeXorPoly() const
1263 Polygon aPol(aRect);
1264 if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1265 if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1267 basegfx::B2DPolyPolygon aRetval;
1268 aRetval.append(aPol.getB2DPolygon());
1269 return aRetval;
1272 basegfx::B2DPolyPolygon SdrTextObj::TakeContour() const
1274 basegfx::B2DPolyPolygon aRetval(SdrAttrObj::TakeContour());
1276 // und nun noch ggf. das BoundRect des Textes dazu
1277 if ( pModel && GetOutlinerParaObject() && !IsFontwork() && !IsContourTextFrame() )
1279 // #80328# using Clone()-Paint() strategy inside TakeContour() leaves a destroyed
1280 // SdrObject as pointer in DrawOutliner. Set *this again in fetching the outliner
1281 // in every case
1282 SdrOutliner& rOutliner=ImpGetDrawOutliner();
1284 Rectangle aAnchor2;
1285 Rectangle aR;
1286 TakeTextRect(rOutliner,aR,FALSE,&aAnchor2);
1287 rOutliner.Clear();
1288 FASTBOOL bFitToSize(IsFitToSize());
1289 if (bFitToSize) aR=aAnchor2;
1290 Polygon aPol(aR);
1291 if (aGeo.nDrehWink!=0) RotatePoly(aPol,aR.TopLeft(),aGeo.nSin,aGeo.nCos);
1293 aRetval.append(aPol.getB2DPolygon());
1296 return aRetval;
1299 void SdrTextObj::RecalcSnapRect()
1301 if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) {
1302 Polygon aPol(aRect);
1303 if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1304 if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1305 maSnapRect=aPol.GetBoundRect();
1306 } else {
1307 maSnapRect=aRect;
1311 sal_uInt32 SdrTextObj::GetSnapPointCount() const
1313 return 4L;
1316 Point SdrTextObj::GetSnapPoint(sal_uInt32 i) const
1318 Point aP;
1319 switch (i) {
1320 case 0: aP=aRect.TopLeft(); break;
1321 case 1: aP=aRect.TopRight(); break;
1322 case 2: aP=aRect.BottomLeft(); break;
1323 case 3: aP=aRect.BottomRight(); break;
1324 default: aP=aRect.Center(); break;
1326 if (aGeo.nShearWink!=0) ShearPoint(aP,aRect.TopLeft(),aGeo.nTan);
1327 if (aGeo.nDrehWink!=0) RotatePoint(aP,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1328 return aP;
1331 void SdrTextObj::ImpCheckMasterCachable()
1333 bNotMasterCachable=FALSE;
1335 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1337 if(!bNotVisibleAsMaster && pOutlinerParaObject && pOutlinerParaObject->IsEditDoc() )
1339 const EditTextObject& rText= pOutlinerParaObject->GetTextObject();
1340 bNotMasterCachable=rText.HasField(SvxPageField::StaticType());
1341 if( !bNotMasterCachable )
1343 bNotMasterCachable=rText.HasField(SvxHeaderField::StaticType());
1344 if( !bNotMasterCachable )
1346 bNotMasterCachable=rText.HasField(SvxFooterField::StaticType());
1347 if( !bNotMasterCachable )
1349 bNotMasterCachable=rText.HasField(SvxDateTimeField::StaticType());
1356 // #101029#: Extracted from ImpGetDrawOutliner()
1357 void SdrTextObj::ImpInitDrawOutliner( SdrOutliner& rOutl ) const
1359 rOutl.SetUpdateMode(FALSE);
1360 USHORT nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
1361 if ( !IsOutlText() )
1362 nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
1363 rOutl.Init( nOutlinerMode );
1365 rOutl.SetGlobalCharStretching(100,100);
1366 ULONG nStat=rOutl.GetControlWord();
1367 nStat&=~(EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE);
1368 rOutl.SetControlWord(nStat);
1369 Size aNullSize;
1370 Size aMaxSize(100000,100000);
1371 rOutl.SetMinAutoPaperSize(aNullSize);
1372 rOutl.SetMaxAutoPaperSize(aMaxSize);
1373 rOutl.SetPaperSize(aMaxSize);
1374 rOutl.ClearPolygon();
1377 SdrOutliner& SdrTextObj::ImpGetDrawOutliner() const
1379 SdrOutliner& rOutl=pModel->GetDrawOutliner(this);
1381 // #101029#: Code extracted to ImpInitDrawOutliner()
1382 ImpInitDrawOutliner( rOutl );
1384 return rOutl;
1387 boost::shared_ptr< SdrOutliner > SdrTextObj::CreateDrawOutliner()
1389 boost::shared_ptr< SdrOutliner > xDrawOutliner( pModel->CreateDrawOutliner(this) );
1390 ImpInitDrawOutliner( *(xDrawOutliner.get()) );
1391 return xDrawOutliner;
1394 // #101029#: Extracted from Paint()
1395 void SdrTextObj::ImpSetupDrawOutlinerForPaint( FASTBOOL bContourFrame,
1396 SdrOutliner& rOutliner,
1397 Rectangle& rTextRect,
1398 Rectangle& rAnchorRect,
1399 Rectangle& rPaintRect,
1400 Fraction& rFitXKorreg ) const
1402 if (!bContourFrame)
1404 // FitToSize erstmal nicht mit ContourFrame
1405 if (IsFitToSize() || IsAutoFit())
1407 ULONG nStat=rOutliner.GetControlWord();
1408 nStat|=EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE;
1409 rOutliner.SetControlWord(nStat);
1412 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
1413 TakeTextRect(rOutliner, rTextRect, FALSE, &rAnchorRect);
1414 rPaintRect = rTextRect;
1416 if (!bContourFrame)
1418 // FitToSize erstmal nicht mit ContourFrame
1419 if (IsFitToSize())
1421 ImpSetCharStretching(rOutliner,rTextRect.GetSize(),rAnchorRect.GetSize(),rFitXKorreg);
1422 rPaintRect=rAnchorRect;
1424 else if (IsAutoFit())
1426 ImpAutoFitText(rOutliner);
1431 void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner ) const
1433 const Size aShapeSize=GetSnapRect().GetSize();
1434 ImpAutoFitText( rOutliner,
1435 Size(aShapeSize.Width()-GetTextLeftDistance()-GetTextRightDistance(),
1436 aShapeSize.Height()-GetTextUpperDistance()-GetTextLowerDistance()),
1437 IsVerticalWriting() );
1440 void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner, const Size& rTextSize, bool bIsVerticalWriting )
1442 // EditEngine formatting is unstable enough for
1443 // line-breaking text that we need some more samples
1445 // loop early-exits if we detect an already attained value
1446 USHORT nMinStretchX=0, nMinStretchY=0;
1447 USHORT aOldStretchXVals[]={0,0,0,0,0,0,0,0,0,0};
1448 const size_t aStretchArySize=sizeof(aOldStretchXVals)/sizeof(*aOldStretchXVals);
1449 for(int i=0; i<aStretchArySize; ++i)
1451 const Size aCurrTextSize = rOutliner.CalcTextSize();
1452 double fFactor(1.0);
1453 if( bIsVerticalWriting )
1454 fFactor = double(rTextSize.Width())/aCurrTextSize.Width();
1455 else
1456 fFactor = double(rTextSize.Height())/aCurrTextSize.Height();
1458 USHORT nCurrStretchX, nCurrStretchY;
1459 rOutliner.GetGlobalCharStretching(nCurrStretchX, nCurrStretchY);
1461 if (fFactor >= 1.0 )
1463 // resulting text area fits into available shape rect -
1464 // err on the larger streching, to optimally fill area
1465 nMinStretchX = std::max(nMinStretchX,nCurrStretchX);
1466 nMinStretchY = std::max(nMinStretchY,nCurrStretchY);
1469 aOldStretchXVals[i] = nCurrStretchX;
1470 if( std::find(aOldStretchXVals, aOldStretchXVals+i, nCurrStretchX) != aOldStretchXVals+i )
1471 break; // same value already attained once; algo is looping, exit
1473 if (fFactor < 1.0 || (fFactor >= 1.0 && nCurrStretchX != 100))
1475 nCurrStretchX = sal::static_int_cast<USHORT>(nCurrStretchX*fFactor);
1476 nCurrStretchY = sal::static_int_cast<USHORT>(nCurrStretchY*fFactor);
1477 rOutliner.SetGlobalCharStretching(std::min(USHORT(100),nCurrStretchX),
1478 std::min(USHORT(100),nCurrStretchY));
1479 OSL_TRACE("SdrTextObj::onEditOutlinerStatusEvent(): zoom is %d", nCurrStretchX);
1483 OSL_TRACE("---- SdrTextObj::onEditOutlinerStatusEvent(): final zoom is %d ----", nMinStretchX);
1484 rOutliner.SetGlobalCharStretching(std::min(USHORT(100),nMinStretchX),
1485 std::min(USHORT(100),nMinStretchY));
1488 void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1490 ImpInitDrawOutliner( rOutl );
1491 UpdateOutlinerFormatting( rOutl, rPaintRect );
1494 void SdrTextObj::UpdateOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1496 Rectangle aTextRect;
1497 Rectangle aAnchorRect;
1498 Fraction aFitXKorreg(1,1);
1500 FASTBOOL bContourFrame=IsContourTextFrame();
1502 ImpSetupDrawOutlinerForPaint( bContourFrame, rOutl, aTextRect, aAnchorRect, rPaintRect, aFitXKorreg );
1504 if( GetModel() )
1506 MapMode aMapMode(GetModel()->GetScaleUnit(), Point(0,0),
1507 GetModel()->GetScaleFraction(),
1508 GetModel()->GetScaleFraction());
1509 rOutl.SetRefMapMode(aMapMode);
1513 ////////////////////////////////////////////////////////////////////////////////////////////////////
1515 OutlinerParaObject* SdrTextObj::GetOutlinerParaObject() const
1517 SdrText* pText = getActiveText();
1518 if( pText )
1519 return pText->GetOutlinerParaObject();
1520 else
1521 return 0;
1524 bool SdrTextObj::HasOutlinerParaObject() const
1526 SdrText* pText = getActiveText();
1527 if( pText && pText->GetOutlinerParaObject() )
1528 return true;
1529 return false;
1532 void SdrTextObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
1534 NbcSetOutlinerParaObjectForText( pTextObject, getActiveText() );
1537 void SdrTextObj::NbcSetOutlinerParaObjectForText( OutlinerParaObject* pTextObject, SdrText* pText )
1539 if( pText )
1540 pText->SetOutlinerParaObject( pTextObject );
1542 if( pText->GetOutlinerParaObject() )
1544 SvxWritingModeItem aWritingMode(pText->GetOutlinerParaObject()->IsVertical()
1545 ? com::sun::star::text::WritingMode_TB_RL
1546 : com::sun::star::text::WritingMode_LR_TB,
1547 SDRATTR_TEXTDIRECTION);
1548 GetProperties().SetObjectItemDirect(aWritingMode);
1551 SetTextSizeDirty();
1552 if (IsTextFrame() && (IsAutoGrowHeight() || IsAutoGrowWidth()))
1553 { // Textrahmen anpassen!
1554 NbcAdjustTextFrameWidthAndHeight();
1556 if (!IsTextFrame())
1558 // Das SnapRect behaelt seine Groesse bei
1559 SetRectsDirty(sal_True);
1562 // always invalidate BoundRect on change
1563 SetBoundRectDirty();
1564 ActionChanged();
1566 ImpSetTextStyleSheetListeners();
1567 ImpCheckMasterCachable();
1570 void SdrTextObj::NbcReformatText()
1572 SdrText* pText = getActiveText();
1573 if( pText && pText->GetOutlinerParaObject() )
1575 pText->ReformatText();
1576 if (bTextFrame)
1578 NbcAdjustTextFrameWidthAndHeight();
1580 else
1582 // Das SnapRect behaelt seine Groesse bei
1583 SetBoundRectDirty();
1584 SetRectsDirty(sal_True);
1586 SetTextSizeDirty();
1587 ActionChanged();
1588 // FME, AW: i22396
1589 // Necessary here since we have no compare operator at the outliner
1590 // para object which may detect changes regarding the combination
1591 // of outliner para data and configuration (e.g., change of
1592 // formatting of text numerals)
1593 GetViewContact().flushViewObjectContacts(false);
1597 void SdrTextObj::ReformatText()
1599 if(GetOutlinerParaObject())
1601 Rectangle aBoundRect0;
1602 if (pUserCall!=NULL)
1603 aBoundRect0=GetLastBoundRect();
1605 // #110094#-14 SendRepaintBroadcast();
1606 NbcReformatText();
1607 SetChanged();
1608 BroadcastObjectChange();
1609 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1613 SdrObjGeoData* SdrTextObj::NewGeoData() const
1615 return new SdrTextObjGeoData;
1618 void SdrTextObj::SaveGeoData(SdrObjGeoData& rGeo) const
1620 SdrAttrObj::SaveGeoData(rGeo);
1621 SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1622 rTGeo.aRect =aRect;
1623 rTGeo.aGeo =aGeo;
1626 void SdrTextObj::RestGeoData(const SdrObjGeoData& rGeo)
1627 { // RectsDirty wird von SdrObject gerufen
1628 SdrAttrObj::RestGeoData(rGeo);
1629 SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1630 aRect =rTGeo.aRect;
1631 aGeo =rTGeo.aGeo;
1632 SetTextSizeDirty();
1635 SdrFitToSizeType SdrTextObj::GetFitToSize() const
1637 SdrFitToSizeType eType = SDRTEXTFIT_NONE;
1639 if(!IsAutoGrowWidth())
1640 eType = ((SdrTextFitToSizeTypeItem&)(GetObjectItem(SDRATTR_TEXT_FITTOSIZE))).GetValue();
1642 return eType;
1645 void SdrTextObj::ForceOutlinerParaObject()
1647 SdrText* pText = getActiveText();
1648 if( pText && (pText->GetOutlinerParaObject() == 0) )
1650 USHORT nOutlMode = OUTLINERMODE_TEXTOBJECT;
1651 if( IsTextFrame() && eTextKind == OBJ_OUTLINETEXT )
1652 nOutlMode = OUTLINERMODE_OUTLINEOBJECT;
1654 pText->ForceOutlinerParaObject( nOutlMode );
1658 sal_Bool SdrTextObj::IsVerticalWriting() const
1660 // #89459#
1661 if(pEdtOutl)
1663 return pEdtOutl->IsVertical();
1666 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1667 if(pOutlinerParaObject)
1669 return pOutlinerParaObject->IsVertical();
1672 return sal_False;
1675 void SdrTextObj::SetVerticalWriting(sal_Bool bVertical)
1677 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1678 if( !pOutlinerParaObject && bVertical )
1680 // we only need to force a outliner para object if the default of
1681 // horizontal text is changed
1682 ForceOutlinerParaObject();
1683 pOutlinerParaObject = GetOutlinerParaObject();
1686 if( pOutlinerParaObject && (pOutlinerParaObject->IsVertical() != (bool)bVertical) )
1688 // get item settings
1689 const SfxItemSet& rSet = GetObjectItemSet();
1690 sal_Bool bAutoGrowWidth = ((SdrTextAutoGrowWidthItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH)).GetValue();
1691 sal_Bool bAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue();
1693 // #103516# Also exchange hor/ver adjust items
1694 SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
1695 SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
1697 // rescue object size
1698 Rectangle aObjectRect = GetSnapRect();
1700 // prepare ItemSet to set exchanged width and height items
1701 SfxItemSet aNewSet(*rSet.GetPool(),
1702 SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
1703 // #103516# Expanded item ranges to also support hor and ver adjust.
1704 SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
1705 SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
1706 0, 0);
1708 aNewSet.Put(rSet);
1709 aNewSet.Put(SdrTextAutoGrowWidthItem(bAutoGrowHeight));
1710 aNewSet.Put(SdrTextAutoGrowHeightItem(bAutoGrowWidth));
1712 // #103516# Exchange horz and vert adjusts
1713 switch(eVert)
1715 case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
1716 case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
1717 case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
1718 case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
1720 switch(eHorz)
1722 case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
1723 case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
1724 case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
1725 case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
1728 SetObjectItemSet(aNewSet);
1730 pOutlinerParaObject = GetOutlinerParaObject();
1731 if( pOutlinerParaObject )
1733 // set ParaObject orientation accordingly
1734 pOutlinerParaObject->SetVertical(bVertical);
1737 // restore object size
1738 SetSnapRect(aObjectRect);
1742 ////////////////////////////////////////////////////////////////////////////////////////////////////
1744 // transformation interface for StarOfficeAPI. This implements support for
1745 // homogen 3x3 matrices containing the transformation of the SdrObject. At the
1746 // moment it contains a shearX, rotation and translation, but for setting all linear
1747 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
1749 ////////////////////////////////////////////////////////////////////////////////////////////////////
1750 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
1751 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
1752 sal_Bool SdrTextObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
1754 // get turn and shear
1755 double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
1756 double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
1758 // get aRect, this is the unrotated snaprect
1759 Rectangle aRectangle(aRect);
1761 // fill other values
1762 basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
1763 basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
1765 // position maybe relative to anchorpos, convert
1766 if( pModel && pModel->IsWriter() )
1768 if(GetAnchorPos().X() || GetAnchorPos().Y())
1770 aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1774 // force MapUnit to 100th mm
1775 SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
1776 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1778 switch(eMapUnit)
1780 case SFX_MAPUNIT_TWIP :
1782 // postion
1783 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
1784 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
1786 // size
1787 aScale.setX(ImplTwipsToMM(aScale.getX()));
1788 aScale.setY(ImplTwipsToMM(aScale.getY()));
1790 break;
1792 default:
1794 DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
1799 // build matrix
1800 rMatrix.identity();
1802 if(!basegfx::fTools::equal(aScale.getX(), 1.0) || !basegfx::fTools::equal(aScale.getY(), 1.0))
1804 rMatrix.scale(aScale.getX(), aScale.getY());
1807 if(!basegfx::fTools::equalZero(fShearX))
1809 rMatrix.shearX(tan(fShearX));
1812 if(!basegfx::fTools::equalZero(fRotate))
1814 // #i78696#
1815 // fRotate is from the old GeoStat and thus mathematically wrong orientated. For
1816 // the linear combination of matrices it needed to be fixed in the API, so it needs to
1817 // be mirrored here
1818 rMatrix.rotate(-fRotate);
1821 if(!aTranslate.equalZero())
1823 rMatrix.translate(aTranslate.getX(), aTranslate.getY());
1826 return sal_False;
1829 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
1830 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
1831 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
1832 void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
1834 // break up matrix
1835 basegfx::B2DTuple aScale;
1836 basegfx::B2DTuple aTranslate;
1837 double fRotate, fShearX;
1838 rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1840 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
1841 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
1842 if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
1844 aScale.setX(fabs(aScale.getX()));
1845 aScale.setY(fabs(aScale.getY()));
1846 fRotate = fmod(fRotate + F_PI, F_2PI);
1849 // reset object shear and rotations
1850 aGeo.nDrehWink = 0;
1851 aGeo.RecalcSinCos();
1852 aGeo.nShearWink = 0;
1853 aGeo.RecalcTan();
1855 // force metric to pool metric
1856 SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
1857 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1859 switch(eMapUnit)
1861 case SFX_MAPUNIT_TWIP :
1863 // position
1864 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
1865 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
1867 // size
1868 aScale.setX(ImplMMToTwips(aScale.getX()));
1869 aScale.setY(ImplMMToTwips(aScale.getY()));
1871 break;
1873 default:
1875 DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
1880 // if anchor is used, make position relative to it
1881 if( pModel && pModel->IsWriter() )
1883 if(GetAnchorPos().X() || GetAnchorPos().Y())
1885 aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1889 // build and set BaseRect (use scale)
1890 Point aPoint = Point();
1891 Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
1892 Rectangle aBaseRect(aPoint, aSize);
1893 SetSnapRect(aBaseRect);
1895 // shear?
1896 if(!basegfx::fTools::equalZero(fShearX))
1898 GeoStat aGeoStat;
1899 aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
1900 aGeoStat.RecalcTan();
1901 Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, FALSE);
1904 // rotation?
1905 if(!basegfx::fTools::equalZero(fRotate))
1907 GeoStat aGeoStat;
1909 // #i78696#
1910 // fRotate is matematically correct, but aGeoStat.nDrehWink is
1911 // mirrored -> mirror value here
1912 aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
1913 aGeoStat.RecalcSinCos();
1914 Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1917 // translate?
1918 if(!aTranslate.equalZero())
1920 Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
1924 bool SdrTextObj::IsRealyEdited() const
1926 return pEdtOutl && pEdtOutl->IsModified();
1929 /////////////////////////////////////////////////////////////////////////////////////////////////
1930 // moved inlines here form hxx
1932 long SdrTextObj::GetEckenradius() const
1934 return ((SdrEckenradiusItem&)(GetObjectItemSet().Get(SDRATTR_ECKENRADIUS))).GetValue();
1937 long SdrTextObj::GetMinTextFrameHeight() const
1939 return ((SdrTextMinFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEHEIGHT))).GetValue();
1942 long SdrTextObj::GetMaxTextFrameHeight() const
1944 return ((SdrTextMaxFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEHEIGHT))).GetValue();
1947 long SdrTextObj::GetMinTextFrameWidth() const
1949 return ((SdrTextMinFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEWIDTH))).GetValue();
1952 long SdrTextObj::GetMaxTextFrameWidth() const
1954 return ((SdrTextMaxFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEWIDTH))).GetValue();
1957 FASTBOOL SdrTextObj::IsFontwork() const
1959 return (bTextFrame) ? FALSE // Default ist FALSE
1960 : ((XFormTextStyleItem&)(GetObjectItemSet().Get(XATTR_FORMTXTSTYLE))).GetValue()!=XFT_NONE;
1963 FASTBOOL SdrTextObj::IsHideContour() const
1965 return (bTextFrame) ? FALSE // Default ist: Nein, kein HideContour; HideContour nicht bei TextFrames
1966 : ((XFormTextHideFormItem&)(GetObjectItemSet().Get(XATTR_FORMTXTHIDEFORM))).GetValue();
1969 FASTBOOL SdrTextObj::IsContourTextFrame() const
1971 return (bTextFrame) ? FALSE // ContourFrame nicht bei normalen TextFrames
1972 : ((SdrTextContourFrameItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_CONTOURFRAME))).GetValue();
1975 long SdrTextObj::GetTextLeftDistance() const
1977 return ((SdrTextLeftDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LEFTDIST))).GetValue();
1980 long SdrTextObj::GetTextRightDistance() const
1982 return ((SdrTextRightDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_RIGHTDIST))).GetValue();
1985 long SdrTextObj::GetTextUpperDistance() const
1987 return ((SdrTextUpperDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_UPPERDIST))).GetValue();
1990 long SdrTextObj::GetTextLowerDistance() const
1992 return ((SdrTextLowerDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LOWERDIST))).GetValue();
1995 SdrTextAniKind SdrTextObj::GetTextAniKind() const
1997 return ((SdrTextAniKindItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIKIND))).GetValue();
2000 SdrTextAniDirection SdrTextObj::GetTextAniDirection() const
2002 return ((SdrTextAniDirectionItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
2005 // #111096#
2006 // Access to thext hidden flag
2007 sal_Bool SdrTextObj::GetTextHidden() const
2009 return mbTextHidden;
2012 void SdrTextObj::NbcSetTextHidden(sal_Bool bNew)
2014 if(bNew != mbTextHidden)
2016 mbTextHidden = bNew;
2020 // #111096#
2021 // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a
2022 // painting rectangle. Rotation is excluded from the returned values.
2023 GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle(
2024 Rectangle& rScrollRectangle, Rectangle& rPaintRectangle)
2026 GDIMetaFile* pRetval = 0L;
2027 SdrOutliner& rOutliner = ImpGetDrawOutliner();
2028 Rectangle aTextRect;
2029 Rectangle aAnchorRect;
2030 Rectangle aPaintRect;
2031 Fraction aFitXKorreg(1,1);
2032 bool bContourFrame(IsContourTextFrame());
2034 // get outliner set up. To avoid getting a somehow rotated MetaFile,
2035 // temporarily disable object rotation.
2036 sal_Int32 nAngle(aGeo.nDrehWink);
2037 aGeo.nDrehWink = 0L;
2038 ImpSetupDrawOutlinerForPaint( bContourFrame, rOutliner, aTextRect, aAnchorRect, aPaintRect, aFitXKorreg );
2039 aGeo.nDrehWink = nAngle;
2041 Rectangle aScrollFrameRect(aPaintRect);
2042 const SfxItemSet& rSet = GetObjectItemSet();
2043 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
2045 if(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection)
2047 aScrollFrameRect.Left() = aAnchorRect.Left();
2048 aScrollFrameRect.Right() = aAnchorRect.Right();
2051 if(SDRTEXTANI_UP == eDirection || SDRTEXTANI_DOWN == eDirection)
2053 aScrollFrameRect.Top() = aAnchorRect.Top();
2054 aScrollFrameRect.Bottom() = aAnchorRect.Bottom();
2057 // create the MetaFile
2058 pRetval = new GDIMetaFile;
2059 VirtualDevice aBlackHole;
2060 aBlackHole.EnableOutput(sal_False);
2061 pRetval->Record(&aBlackHole);
2062 Point aPaintPos = aPaintRect.TopLeft();
2064 rOutliner.Draw(&aBlackHole, aPaintPos);
2066 pRetval->Stop();
2067 pRetval->WindStart();
2069 // return PaintRectanglePixel and pRetval;
2070 rScrollRectangle = aScrollFrameRect;
2071 rPaintRectangle = aPaintRect;
2073 return pRetval;
2076 // #111096#
2077 // Access to TextAnimationAllowed flag
2078 bool SdrTextObj::IsTextAnimationAllowed() const
2080 return mbTextAnimationAllowed;
2083 FASTBOOL SdrTextObj::IsAutoFit() const
2085 return GetFitToSize()==SDRTEXTFIT_AUTOFIT;
2088 FASTBOOL SdrTextObj::IsFitToSize() const
2090 const SdrFitToSizeType eFit=GetFitToSize();
2091 return (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
2094 void SdrTextObj::SetTextAnimationAllowed(sal_Bool bNew)
2096 if(mbTextAnimationAllowed != bNew)
2098 mbTextAnimationAllowed = bNew;
2099 ActionChanged();
2103 /** called from the SdrObjEditView during text edit when the status of the edit outliner changes */
2104 void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
2106 const sal_uInt32 nStat = pEditStatus->GetStatusWord();
2107 const bool bGrowX=(nStat & EE_STAT_TEXTWIDTHCHANGED) !=0;
2108 const bool bGrowY=(nStat & EE_STAT_TEXTHEIGHTCHANGED) !=0;
2109 if(bTextFrame && (bGrowX || bGrowY))
2111 if ((bGrowX && IsAutoGrowWidth()) || (bGrowY && IsAutoGrowHeight()))
2113 AdjustTextFrameWidthAndHeight();
2115 else if (IsAutoFit() && !mbInDownScale)
2117 OSL_ASSERT(pEdtOutl);
2118 mbInDownScale = sal_True;
2120 // sucks that we cannot disable paints via
2121 // pEdtOutl->SetUpdateMode(FALSE) - but EditEngine skips
2122 // formatting as well, then.
2123 ImpAutoFitText(*pEdtOutl);
2124 mbInDownScale = sal_False;
2129 /** returns the currently active text. */
2130 SdrText* SdrTextObj::getActiveText() const
2132 if( !mpText )
2133 return getText( 0 );
2134 else
2135 return mpText;
2138 /** returns the nth available text. */
2139 SdrText* SdrTextObj::getText( sal_Int32 nIndex ) const
2141 if( nIndex == 0 )
2143 if( mpText == 0 )
2144 const_cast< SdrTextObj* >(this)->mpText = new SdrText( *(const_cast< SdrTextObj* >(this)) );
2145 return mpText;
2147 else
2149 return 0;
2153 /** returns the number of texts available for this object. */
2154 sal_Int32 SdrTextObj::getTextCount() const
2156 return 1;
2159 /** changes the current active text */
2160 void SdrTextObj::setActiveText( sal_Int32 /*nIndex*/ )
2164 /** returns the index of the text that contains the given point or -1 */
2165 sal_Int32 SdrTextObj::CheckTextHit(const Point& /*rPnt*/) const
2167 return 0;
2170 void SdrTextObj::SetObjectItemNoBroadcast(const SfxPoolItem& rItem)
2172 static_cast< sdr::properties::TextProperties& >(GetProperties()).SetObjectItemNoBroadcast(rItem);
2175 /////////////////////////////////////////////////////////////////////////////////////////////////
2177 // Konzept des TextObjekts:
2178 // ~~~~~~~~~~~~~~~~~~~~~~~~
2179 // Attribute/Varianten:
2180 // - BOOL Textrahmen / beschriftetes Zeichenobjekt
2181 // - BOOL FontWork (wenn nicht Textrahmen und nicht ContourTextFrame)
2182 // - BOOL ContourTextFrame (wenn nicht Textrahmen und nicht Fontwork)
2183 // - long Drehwinkel (wenn nicht FontWork)
2184 // - long Textrahmenabstaende (wenn nicht FontWork)
2185 // - BOOL FitToSize (wenn nicht FontWork)
2186 // - BOOL AutoGrowingWidth/Height (wenn nicht FitToSize und nicht FontWork)
2187 // - long Min/MaxFrameWidth/Height (wenn AutoGrowingWidth/Height)
2188 // - enum Horizontale Textverankerung Links,Mitte,Rechts,Block,Stretch(ni)
2189 // - enum Vertikale Textverankerung Oben,Mitte,Unten,Block,Stretch(ni)
2190 // - enum Laufschrift (wenn nicht FontWork)
2192 // Jedes abgeleitete Objekt ist entweder ein Textrahmen (bTextFrame=TRUE)
2193 // oder ein beschriftetes Zeichenobjekt (bTextFrame=FALSE).
2195 // Defaultverankerung von Textrahmen:
2196 // SDRTEXTHORZADJUST_BLOCK, SDRTEXTVERTADJUST_TOP
2197 // = statische Pooldefaults
2198 // Defaultverankerung von beschrifteten Zeichenobjekten:
2199 // SDRTEXTHORZADJUST_CENTER, SDRTEXTVERTADJUST_CENTER
2200 // durch harte Attributierung von SdrAttrObj
2202 // Jedes vom SdrTextObj abgeleitete Objekt muss ein "UnrotatedSnapRect"
2203 // (->TakeUnrotatedSnapRect()) liefern (Drehreferenz ist TopLeft dieses
2204 // Rechtecks (aGeo.nDrehWink)), welches die Grundlage der Textverankerung
2205 // bildet. Von diesem werden dann ringsum die Textrahmenabstaende abgezogen;
2206 // das Ergebnis ist der Ankerbereich (->TakeTextAnchorRect()). Innerhalb
2207 // dieses Bereichs wird dann in Abhaengigkeit von der horizontalen und
2208 // vertikalen Ausrichtung (SdrTextVertAdjust,SdrTextHorzAdjust) der Ankerpunkt
2209 // sowie der Ausgabebereich bestimmt. Bei beschrifteten Grafikobjekten kann
2210 // der Ausgabebereich durchaus groesser als der Ankerbereich werden, bei
2211 // Textrahmen ist er stets kleiner oder gleich (ausser bei negativen Textrahmen-
2212 // abstaenden).
2214 // FitToSize hat Prioritaet vor Textverankerung und AutoGrowHeight/Width. Der
2215 // Ausgabebereich ist bei FitToSize immer genau der Ankerbereich. Weiterhin
2216 // gibt es bei FitToSize keinen automatischen Zeilenumbruch.
2218 // ContourTextFrame:
2219 // - long Drehwinkel
2220 // - long Textrahmenabstaende spaeter vielleicht
2221 // - BOOL FitToSize spaeter vielleicht
2222 // - BOOL AutoGrowingWidth/Height viel spaeter vielleicht
2223 // - long Min/MaxFrameWidth/Height viel spaeter vielleicht
2224 // - enum Horizontale Textverankerung spaeter vielleicht, erstmal Links, Absatz zentr.
2225 // - enum Vertikale Textverankerung spaeter vielleicht, erstmal oben
2226 // - enum Laufschrift spaeter vielleicht (evtl. sogar mit korrektem Clipping)
2228 // Bei Aenderungen zu beachten:
2229 // - Paint
2230 // - HitTest
2231 // - ConvertToPoly
2232 // - Edit
2233 // - Drucken,Speichern, Paint in Nachbarview waerend Edit
2234 // - ModelChanged (z.B. durch NachbarView oder Lineale) waerend Edit
2235 // - FillColorChanged waerend Edit
2236 // - uvm...
2238 /////////////////////////////////////////////////////////////////////////////////////////////////