1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <comphelper/string.hxx>
22 #include <svx/svdotext.hxx>
23 #include <svx/svdpagv.hxx>
24 #include <svx/svdview.hxx>
25 #include <svx/svdpage.hxx>
26 #include <svx/svdetc.hxx>
27 #include <svx/svdoutl.hxx>
28 #include <svx/svdmodel.hxx>
29 #include "svdglob.hxx"
30 #include "svx/svdstr.hrc"
31 #include <editeng/writingmodeitem.hxx>
32 #include <svx/sdtfchim.hxx>
33 #include <svtools/colorcfg.hxx>
34 #include <editeng/editdata.hxx>
35 #include <editeng/eeitem.hxx>
36 #include <editeng/editstat.hxx>
37 #include <editeng/outlobj.hxx>
38 #include <editeng/editobj.hxx>
39 #include <editeng/outliner.hxx>
40 #include <editeng/fhgtitem.hxx>
41 #include <svl/itempool.hxx>
42 #include <editeng/adjustitem.hxx>
43 #include <editeng/flditem.hxx>
44 #include <svx/xftouit.hxx>
45 #include <tools/helpers.hxx>
46 #include <svx/xflgrit.hxx>
47 #include <svx/svdpool.hxx>
48 #include <svx/xflclit.hxx>
49 #include <svl/style.hxx>
50 #include <editeng/editeng.hxx>
51 #include <svl/itemiter.hxx>
52 #include <sdr/properties/textproperties.hxx>
53 #include <vcl/metaact.hxx>
54 #include <svx/sdr/contact/viewcontactoftextobj.hxx>
55 #include <basegfx/tuple/b2dtuple.hxx>
56 #include <basegfx/matrix/b2dhommatrix.hxx>
57 #include <basegfx/polygon/b2dpolygon.hxx>
58 #include <drawinglayer/geometry/viewinformation2d.hxx>
59 #include <vcl/virdev.hxx>
60 #include <basegfx/matrix/b2dhommatrixtools.hxx>
61 #include "svdconv.hxx"
63 using namespace com::sun::star
;
66 // BaseProperties section
68 sdr::properties::BaseProperties
* SdrTextObj::CreateObjectSpecificProperties()
70 return new sdr::properties::TextProperties(*this);
74 // DrawContact section
76 sdr::contact::ViewContact
* SdrTextObj::CreateObjectSpecificViewContact()
78 return new sdr::contact::ViewContactOfTextObj(*this);
83 TYPEINIT1(SdrTextObj
,SdrAttrObj
);
85 SdrTextObj::SdrTextObj()
89 pFormTextBoundRect(NULL
),
94 bPortionInfoChecked
=false;
98 bDisableAutoWidthOnDragging
=false;
100 mbInEditMode
= false;
101 mbTextHidden
= false;
102 mbTextAnimationAllowed
= true;
103 maTextEditOffset
= Point(0, 0);
106 mbSupportTextIndentingOnLineWidthChange
= true;
107 mbInDownScale
= false;
110 SdrTextObj::SdrTextObj(const Rectangle
& rNewRect
)
115 pFormTextBoundRect(NULL
),
118 bTextSizeDirty
=false;
120 bPortionInfoChecked
=false;
124 bDisableAutoWidthOnDragging
=false;
125 ImpJustifyRect(maRect
);
127 mbInEditMode
= false;
128 mbTextHidden
= false;
129 mbTextAnimationAllowed
= true;
130 mbInDownScale
= false;
131 maTextEditOffset
= Point(0, 0);
134 mbSupportTextIndentingOnLineWidthChange
= true;
137 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind
)
141 pFormTextBoundRect(NULL
),
142 eTextKind(eNewTextKind
)
144 bTextSizeDirty
=false;
146 bPortionInfoChecked
=false;
150 bDisableAutoWidthOnDragging
=false;
152 mbInEditMode
= false;
153 mbTextHidden
= false;
154 mbTextAnimationAllowed
= true;
155 mbInDownScale
= false;
156 maTextEditOffset
= Point(0, 0);
159 mbSupportTextIndentingOnLineWidthChange
= true;
162 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind
, const Rectangle
& rNewRect
)
167 pFormTextBoundRect(NULL
),
168 eTextKind(eNewTextKind
)
170 bTextSizeDirty
=false;
172 bPortionInfoChecked
=false;
176 bDisableAutoWidthOnDragging
=false;
177 ImpJustifyRect(maRect
);
179 mbInEditMode
= false;
180 mbTextHidden
= false;
181 mbTextAnimationAllowed
= true;
182 mbInDownScale
= false;
183 maTextEditOffset
= Point(0, 0);
186 mbSupportTextIndentingOnLineWidthChange
= true;
189 SdrTextObj::~SdrTextObj()
193 SdrOutliner
& rOutl
= pModel
->GetHitTestOutliner();
194 if( rOutl
.GetTextObj() == this )
195 rOutl
.SetTextObj( NULL
);
200 delete pFormTextBoundRect
;
205 void SdrTextObj::FitFrameToTextSize()
207 DBG_ASSERT(pModel
!=NULL
,"SdrTextObj::FitFrameToTextSize(): pModel=NULL!");
208 ImpJustifyRect(maRect
);
210 SdrText
* pText
= getActiveText();
211 if( pText
!=NULL
&& pText
->GetOutlinerParaObject() && pModel
!=NULL
)
213 SdrOutliner
& rOutliner
=ImpGetDrawOutliner();
214 rOutliner
.SetPaperSize(Size(maRect
.Right()-maRect
.Left(),maRect
.Bottom()-maRect
.Top()));
215 rOutliner
.SetUpdateMode(true);
216 rOutliner
.SetText(*pText
->GetOutlinerParaObject());
217 Size
aNewSize(rOutliner
.CalcTextSize());
219 aNewSize
.Width()++; // because of possible rounding errors
220 aNewSize
.Width()+=GetTextLeftDistance()+GetTextRightDistance();
221 aNewSize
.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
222 Rectangle
aNewRect(maRect
);
223 aNewRect
.SetSize(aNewSize
);
224 ImpJustifyRect(aNewRect
);
225 if (aNewRect
!=maRect
) {
226 SetLogicRect(aNewRect
);
231 void SdrTextObj::NbcSetText(const OUString
& rStr
)
233 SdrOutliner
& rOutliner
=ImpGetDrawOutliner();
234 rOutliner
.SetStyleSheet( 0, GetStyleSheet());
235 rOutliner
.SetUpdateMode(true);
236 rOutliner
.SetText(rStr
,rOutliner
.GetParagraph( 0 ));
237 OutlinerParaObject
* pNewText
=rOutliner
.CreateParaObject();
238 Size
aSiz(rOutliner
.CalcTextSize());
240 NbcSetOutlinerParaObject(pNewText
);
242 bTextSizeDirty
=false;
245 void SdrTextObj::SetText(const OUString
& rStr
)
247 Rectangle aBoundRect0
; if (pUserCall
!=NULL
) aBoundRect0
=GetLastBoundRect();
250 BroadcastObjectChange();
251 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
254 void SdrTextObj::NbcSetText(SvStream
& rInput
, const OUString
& rBaseURL
, sal_uInt16 eFormat
)
256 SdrOutliner
& rOutliner
=ImpGetDrawOutliner();
257 rOutliner
.SetStyleSheet( 0, GetStyleSheet());
258 rOutliner
.Read(rInput
,rBaseURL
,eFormat
);
259 OutlinerParaObject
* pNewText
=rOutliner
.CreateParaObject();
260 rOutliner
.SetUpdateMode(true);
261 Size
aSiz(rOutliner
.CalcTextSize());
263 NbcSetOutlinerParaObject(pNewText
);
265 bTextSizeDirty
=false;
268 void SdrTextObj::SetText(SvStream
& rInput
, const OUString
& rBaseURL
, sal_uInt16 eFormat
)
270 Rectangle aBoundRect0
; if (pUserCall
!=NULL
) aBoundRect0
=GetLastBoundRect();
271 NbcSetText(rInput
,rBaseURL
,eFormat
);
273 BroadcastObjectChange();
274 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
277 const Size
& SdrTextObj::GetTextSize() const
282 SdrText
* pText
= getActiveText();
283 if( pText
&& pText
->GetOutlinerParaObject ())
285 SdrOutliner
& rOutliner
=ImpGetDrawOutliner();
286 rOutliner
.SetText(*pText
->GetOutlinerParaObject());
287 rOutliner
.SetUpdateMode(true);
288 aSiz
=rOutliner
.CalcTextSize();
291 // casting to nonconst twice
292 const_cast<SdrTextObj
*>(this)->aTextSize
=aSiz
;
293 const_cast<SdrTextObj
*>(this)->bTextSizeDirty
=false;
298 bool SdrTextObj::IsAutoGrowHeight() const
301 return false; // AutoGrow only together with TextFrames
303 const SfxItemSet
& rSet
= GetObjectItemSet();
304 bool bRet
= static_cast<const SdrOnOffItem
&>(rSet
.Get(SDRATTR_TEXT_AUTOGROWHEIGHT
)).GetValue();
308 SdrTextAniKind eAniKind
= static_cast<const SdrTextAniKindItem
&>(rSet
.Get(SDRATTR_TEXT_ANIKIND
)).GetValue();
310 if(eAniKind
== SDRTEXTANI_SCROLL
|| eAniKind
== SDRTEXTANI_ALTERNATE
|| eAniKind
== SDRTEXTANI_SLIDE
)
312 SdrTextAniDirection eDirection
= static_cast<const SdrTextAniDirectionItem
&>(rSet
.Get(SDRATTR_TEXT_ANIDIRECTION
)).GetValue();
314 if(eDirection
== SDRTEXTANI_UP
|| eDirection
== SDRTEXTANI_DOWN
)
323 bool SdrTextObj::IsAutoGrowWidth() const
326 return false; // AutoGrow only together with TextFrames
328 const SfxItemSet
& rSet
= GetObjectItemSet();
329 bool bRet
= static_cast<const SdrOnOffItem
&>(rSet
.Get(SDRATTR_TEXT_AUTOGROWWIDTH
)).GetValue();
331 bool bInEditMOde
= IsInEditMode();
333 if(!bInEditMOde
&& bRet
)
335 SdrTextAniKind eAniKind
= static_cast<const SdrTextAniKindItem
&>(rSet
.Get(SDRATTR_TEXT_ANIKIND
)).GetValue();
337 if(eAniKind
== SDRTEXTANI_SCROLL
|| eAniKind
== SDRTEXTANI_ALTERNATE
|| eAniKind
== SDRTEXTANI_SLIDE
)
339 SdrTextAniDirection eDirection
= static_cast<const SdrTextAniDirectionItem
&>(rSet
.Get(SDRATTR_TEXT_ANIDIRECTION
)).GetValue();
341 if(eDirection
== SDRTEXTANI_LEFT
|| eDirection
== SDRTEXTANI_RIGHT
)
350 SdrTextHorzAdjust
SdrTextObj::GetTextHorizontalAdjust() const
352 return GetTextHorizontalAdjust(GetObjectItemSet());
355 SdrTextHorzAdjust
SdrTextObj::GetTextHorizontalAdjust(const SfxItemSet
& rSet
) const
357 if(IsContourTextFrame())
358 return SDRTEXTHORZADJUST_BLOCK
;
360 SdrTextHorzAdjust eRet
= static_cast<const SdrTextHorzAdjustItem
&>(rSet
.Get(SDRATTR_TEXT_HORZADJUST
)).GetValue();
362 bool bInEditMode
= IsInEditMode();
364 if(!bInEditMode
&& eRet
== SDRTEXTHORZADJUST_BLOCK
)
366 SdrTextAniKind eAniKind
= static_cast<const SdrTextAniKindItem
&>(rSet
.Get(SDRATTR_TEXT_ANIKIND
)).GetValue();
368 if(eAniKind
== SDRTEXTANI_SCROLL
|| eAniKind
== SDRTEXTANI_ALTERNATE
|| eAniKind
== SDRTEXTANI_SLIDE
)
370 SdrTextAniDirection eDirection
= static_cast<const SdrTextAniDirectionItem
&>(rSet
.Get(SDRATTR_TEXT_ANIDIRECTION
)).GetValue();
372 if(eDirection
== SDRTEXTANI_LEFT
|| eDirection
== SDRTEXTANI_RIGHT
)
374 eRet
= SDRTEXTHORZADJUST_LEFT
;
380 } // defaults: BLOCK (justify) for text frame, CENTER for captions of drawing objects
382 SdrTextVertAdjust
SdrTextObj::GetTextVerticalAdjust() const
384 return GetTextVerticalAdjust(GetObjectItemSet());
387 SdrTextVertAdjust
SdrTextObj::GetTextVerticalAdjust(const SfxItemSet
& rSet
) const
389 if(IsContourTextFrame())
390 return SDRTEXTVERTADJUST_TOP
;
392 // Take care for vertical text animation here
393 SdrTextVertAdjust eRet
= static_cast<const SdrTextVertAdjustItem
&>(rSet
.Get(SDRATTR_TEXT_VERTADJUST
)).GetValue();
394 bool bInEditMode
= IsInEditMode();
396 // Take care for vertical text animation here
397 if(!bInEditMode
&& eRet
== SDRTEXTVERTADJUST_BLOCK
)
399 SdrTextAniKind eAniKind
= static_cast<const SdrTextAniKindItem
&>(rSet
.Get(SDRATTR_TEXT_ANIKIND
)).GetValue();
401 if(eAniKind
== SDRTEXTANI_SCROLL
|| eAniKind
== SDRTEXTANI_ALTERNATE
|| eAniKind
== SDRTEXTANI_SLIDE
)
403 SdrTextAniDirection eDirection
= static_cast<const SdrTextAniDirectionItem
&>(rSet
.Get(SDRATTR_TEXT_ANIDIRECTION
)).GetValue();
405 if(eDirection
== SDRTEXTANI_LEFT
|| eDirection
== SDRTEXTANI_RIGHT
)
407 eRet
= SDRTEXTVERTADJUST_TOP
;
413 } // defaults: TOP for text frame, CENTER for captions of drawing objects
415 void SdrTextObj::ImpJustifyRect(Rectangle
& rRect
)
417 if (!rRect
.IsEmpty()) {
419 if (rRect
.Left()==rRect
.Right()) rRect
.Right()++;
420 if (rRect
.Top()==rRect
.Bottom()) rRect
.Bottom()++;
424 void SdrTextObj::ImpCheckShear()
426 if (bNoShear
&& aGeo
.nShearAngle
!=0) {
432 void SdrTextObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
434 bool bNoTextFrame
=!IsTextFrame();
435 rInfo
.bResizeFreeAllowed
=bNoTextFrame
|| aGeo
.nRotationAngle
%9000==0;
436 rInfo
.bResizePropAllowed
=true;
437 rInfo
.bRotateFreeAllowed
=true;
438 rInfo
.bRotate90Allowed
=true;
439 rInfo
.bMirrorFreeAllowed
=bNoTextFrame
;
440 rInfo
.bMirror45Allowed
=bNoTextFrame
;
441 rInfo
.bMirror90Allowed
=bNoTextFrame
;
443 // allow transparency
444 rInfo
.bTransparenceAllowed
= true;
446 // gradient depends on fillstyle
447 drawing::FillStyle eFillStyle
= static_cast<const XFillStyleItem
&>(GetObjectItem(XATTR_FILLSTYLE
)).GetValue();
448 rInfo
.bGradientAllowed
= (eFillStyle
== drawing::FillStyle_GRADIENT
);
449 rInfo
.bShearAllowed
=bNoTextFrame
;
450 rInfo
.bEdgeRadiusAllowed
=true;
451 bool bCanConv
=ImpCanConvTextToCurve();
452 rInfo
.bCanConvToPath
=bCanConv
;
453 rInfo
.bCanConvToPoly
=bCanConv
;
454 rInfo
.bCanConvToPathLineToArea
=bCanConv
;
455 rInfo
.bCanConvToPolyLineToArea
=bCanConv
;
456 rInfo
.bCanConvToContour
= (rInfo
.bCanConvToPoly
|| LineGeometryUsageIsNecessary());
459 sal_uInt16
SdrTextObj::GetObjIdentifier() const
461 return sal_uInt16(eTextKind
);
464 bool SdrTextObj::HasTextImpl( SdrOutliner
* pOutliner
)
469 Paragraph
* p1stPara
=pOutliner
->GetParagraph( 0 );
470 sal_Int32 nParaCount
=pOutliner
->GetParagraphCount();
476 // if it is only one paragraph, check if that paragraph is empty
477 if( pOutliner
->GetText(p1stPara
).isEmpty() )
486 bool SdrTextObj::HasEditText() const
488 return HasTextImpl( pEdtOutl
);
491 void SdrTextObj::SetPage(SdrPage
* pNewPage
)
493 bool bRemove
=pNewPage
==NULL
&& pPage
!=NULL
;
494 bool bInsert
=pNewPage
!=NULL
&& pPage
==NULL
;
495 bool bLinked
=IsLinkedText();
497 if (bLinked
&& bRemove
) {
501 SdrAttrObj::SetPage(pNewPage
);
503 if (bLinked
&& bInsert
) {
508 void SdrTextObj::SetModel(SdrModel
* pNewModel
)
510 SdrModel
* pOldModel
=pModel
;
511 bool bLinked
=IsLinkedText();
512 bool bChg
=pNewModel
!=pModel
;
519 SdrAttrObj::SetModel(pNewModel
);
523 if( pNewModel
!= 0 && pOldModel
!= 0 )
526 sal_Int32 nCount
= getTextCount();
527 for( sal_Int32 nText
= 0; nText
< nCount
; nText
++ )
529 SdrText
* pText
= getText( nText
);
531 pText
->SetModel( pNewModel
);
541 bool SdrTextObj::NbcSetEckenradius(long nRad
)
543 SetObjectItem(makeSdrEckenradiusItem(nRad
));
547 // #115391# This implementation is based on the object size (aRect) and the
548 // states of IsAutoGrowWidth/Height to correctly set TextMinFrameWidth/Height
549 void SdrTextObj::AdaptTextMinSize()
552 // Only do this for text frame.
555 if (pModel
&& pModel
->IsPasteResize())
556 // Don't do this during paste resize.
559 const bool bW
= IsAutoGrowWidth();
560 const bool bH
= IsAutoGrowHeight();
563 // No auto grow requested. Bail out.
567 *GetObjectItemSet().GetPool(),
568 SDRATTR_TEXT_MINFRAMEHEIGHT
, SDRATTR_TEXT_AUTOGROWHEIGHT
,
569 SDRATTR_TEXT_MINFRAMEWIDTH
, SDRATTR_TEXT_AUTOGROWWIDTH
, // contains SDRATTR_TEXT_MAXFRAMEWIDTH
574 // Set minimum width.
575 const long nDist
= GetTextLeftDistance() + GetTextRightDistance();
576 const long nW
= std::max
<long>(0, maRect
.GetWidth() - 1 - nDist
); // text width without margins
578 aSet
.Put(makeSdrTextMinFrameWidthItem(nW
));
580 if(!IsVerticalWriting() && bDisableAutoWidthOnDragging
)
582 bDisableAutoWidthOnDragging
= true;
583 aSet
.Put(makeSdrTextAutoGrowWidthItem(false));
589 // Set Minimum height.
590 const long nDist
= GetTextUpperDistance() + GetTextLowerDistance();
591 const long nH
= std::max
<long>(0, maRect
.GetHeight() - 1 - nDist
); // text height without margins
593 aSet
.Put(makeSdrTextMinFrameHeightItem(nH
));
595 if(IsVerticalWriting() && bDisableAutoWidthOnDragging
)
597 bDisableAutoWidthOnDragging
= false;
598 aSet
.Put(makeSdrTextAutoGrowHeightItem(false));
602 SetObjectItemSet(aSet
);
605 void SdrTextObj::ImpSetContourPolygon( SdrOutliner
& rOutliner
, Rectangle
& rAnchorRect
, bool bLineWidth
) const
607 basegfx::B2DPolyPolygon
aXorPolyPolygon(TakeXorPoly());
608 basegfx::B2DPolyPolygon
* pContourPolyPolygon
= 0L;
609 basegfx::B2DHomMatrix
aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
610 -rAnchorRect
.Left(), -rAnchorRect
.Top()));
612 if(aGeo
.nRotationAngle
)
615 aMatrix
.rotate(-aGeo
.nRotationAngle
* nPi180
);
618 aXorPolyPolygon
.transform(aMatrix
);
622 // Take line width into account.
623 // When doing the hit test, avoid this. (Performance!)
624 pContourPolyPolygon
= new basegfx::B2DPolyPolygon();
626 // test if shadow needs to be avoided for TakeContour()
627 const SfxItemSet
& rSet
= GetObjectItemSet();
628 bool bShadowOn
= static_cast<const SdrOnOffItem
&>(rSet
.Get(SDRATTR_SHADOW
)).GetValue();
631 // Remember TextObject currently set at the DrawOutliner, it WILL be
632 // replaced during calculating the outline since it uses an own paint
633 // and that one uses the DrawOutliner, too.
634 const SdrTextObj
* pLastTextObject
= rOutliner
.GetTextObj();
639 SdrObject
* pCopy
= Clone();
640 pCopy
->SetMergedItem(makeSdrShadowItem(false));
641 *pContourPolyPolygon
= pCopy
->TakeContour();
642 SdrObject::Free( pCopy
);
646 *pContourPolyPolygon
= TakeContour();
650 // restore remembered text object
651 if(pLastTextObject
!= rOutliner
.GetTextObj())
653 rOutliner
.SetTextObj(pLastTextObject
);
656 pContourPolyPolygon
->transform(aMatrix
);
659 rOutliner
.SetPolygon(aXorPolyPolygon
, pContourPolyPolygon
);
660 delete pContourPolyPolygon
;
663 void SdrTextObj::TakeUnrotatedSnapRect(Rectangle
& rRect
) const
668 void SdrTextObj::TakeTextAnchorRect(Rectangle
& rAnchorRect
) const
670 long nLeftDist
=GetTextLeftDistance();
671 long nRightDist
=GetTextRightDistance();
672 long nUpperDist
=GetTextUpperDistance();
673 long nLowerDist
=GetTextLowerDistance();
674 Rectangle
aAnkRect(maRect
); // the rectangle in which we anchor
675 bool bFrame
=IsTextFrame();
677 TakeUnrotatedSnapRect(aAnkRect
);
679 Point
aRotateRef(aAnkRect
.TopLeft());
680 aAnkRect
.Left()+=nLeftDist
;
681 aAnkRect
.Top()+=nUpperDist
;
682 aAnkRect
.Right()-=nRightDist
;
683 aAnkRect
.Bottom()-=nLowerDist
;
685 // Since sizes may be bigger than the object bounds it is necessary to
686 // justify the rect now.
687 ImpJustifyRect(aAnkRect
);
690 // TODO: Optimize this.
691 if (aAnkRect
.GetWidth()<2) aAnkRect
.Right()=aAnkRect
.Left()+1; // minimum size h and v: 2 px
692 if (aAnkRect
.GetHeight()<2) aAnkRect
.Bottom()=aAnkRect
.Top()+1;
694 if (aGeo
.nRotationAngle
!=0) {
695 Point
aTmpPt(aAnkRect
.TopLeft());
696 RotatePoint(aTmpPt
,aRotateRef
,aGeo
.nSin
,aGeo
.nCos
);
697 aTmpPt
-=aAnkRect
.TopLeft();
698 aAnkRect
.Move(aTmpPt
.X(),aTmpPt
.Y());
700 rAnchorRect
=aAnkRect
;
703 void SdrTextObj::TakeTextRect( SdrOutliner
& rOutliner
, Rectangle
& rTextRect
, bool bNoEditText
,
704 Rectangle
* pAnchorRect
, bool bLineWidth
) const
706 Rectangle aAnkRect
; // the rectangle in which we anchor
707 TakeTextAnchorRect(aAnkRect
);
708 SdrTextVertAdjust eVAdj
=GetTextVerticalAdjust();
709 SdrTextHorzAdjust eHAdj
=GetTextHorizontalAdjust();
710 SdrTextAniKind eAniKind
=GetTextAniKind();
711 SdrTextAniDirection eAniDirection
=GetTextAniDirection();
713 bool bFitToSize(IsFitToSize());
714 bool bContourFrame
=IsContourTextFrame();
716 bool bFrame
=IsTextFrame();
717 EEControlBits nStat0
=rOutliner
.GetControlWord();
721 rOutliner
.SetControlWord(nStat0
|EEControlBits::AUTOPAGESIZE
);
722 rOutliner
.SetMinAutoPaperSize(aNullSize
);
723 rOutliner
.SetMaxAutoPaperSize(Size(1000000,1000000));
726 if (!bFitToSize
&& !bContourFrame
)
728 long nAnkWdt
=aAnkRect
.GetWidth();
729 long nAnkHgt
=aAnkRect
.GetHeight();
735 bool bInEditMode
= IsInEditMode();
737 if (!bInEditMode
&& (eAniKind
==SDRTEXTANI_SCROLL
|| eAniKind
==SDRTEXTANI_ALTERNATE
|| eAniKind
==SDRTEXTANI_SLIDE
))
739 // unlimited paper size for ticker text
740 if (eAniDirection
==SDRTEXTANI_LEFT
|| eAniDirection
==SDRTEXTANI_RIGHT
) nWdt
=1000000;
741 if (eAniDirection
==SDRTEXTANI_UP
|| eAniDirection
==SDRTEXTANI_DOWN
) nHgt
=1000000;
744 // #i119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
745 if(IsVerticalWriting())
754 rOutliner
.SetMaxAutoPaperSize(Size(nWdt
,nHgt
));
757 // New try with _BLOCK for hor and ver after completely
758 // supporting full width for vertical text.
759 if(SDRTEXTHORZADJUST_BLOCK
== eHAdj
&& !IsVerticalWriting())
761 rOutliner
.SetMinAutoPaperSize(Size(nAnkWdt
, 0));
764 if(SDRTEXTVERTADJUST_BLOCK
== eVAdj
&& IsVerticalWriting())
766 rOutliner
.SetMinAutoPaperSize(Size(0, nAnkHgt
));
770 rOutliner
.SetPaperSize(aNullSize
);
772 ImpSetContourPolygon( rOutliner
, aAnkRect
, bLineWidth
);
774 // put text into the outliner, if available from the edit outliner
775 SdrText
* pText
= getActiveText();
776 OutlinerParaObject
* pOutlinerParaObject
= pText
? pText
->GetOutlinerParaObject() : 0;
777 OutlinerParaObject
* pPara
= (pEdtOutl
&& !bNoEditText
) ? pEdtOutl
->CreateParaObject() : pOutlinerParaObject
;
781 bool bHitTest
= false;
783 bHitTest
= &pModel
->GetHitTestOutliner() == &rOutliner
;
785 const SdrTextObj
* pTestObj
= rOutliner
.GetTextObj();
786 if( !pTestObj
|| !bHitTest
|| pTestObj
!= this ||
787 pTestObj
->GetOutlinerParaObject() != pOutlinerParaObject
)
789 if( bHitTest
) // #i33696# take back fix #i27510#
791 rOutliner
.SetTextObj( this );
792 rOutliner
.SetFixedCellHeight(static_cast<const SdrTextFixedCellHeightItem
&>(GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT
)).GetValue());
795 rOutliner
.SetUpdateMode(true);
796 rOutliner
.SetText(*pPara
);
801 rOutliner
.SetTextObj( NULL
);
804 if (pEdtOutl
&& !bNoEditText
&& pPara
)
807 rOutliner
.SetUpdateMode(true);
808 rOutliner
.SetControlWord(nStat0
);
811 pText
->CheckPortionInfo(rOutliner
);
813 Point
aTextPos(aAnkRect
.TopLeft());
814 Size
aTextSiz(rOutliner
.GetPaperSize()); // GetPaperSize() adds a little tolerance, right?
816 // For draw objects containing text correct hor/ver alignment if text is bigger
817 // than the object itself. Without that correction, the text would always be
818 // formatted to the left edge (or top edge when vertical) of the draw object.
821 if(aAnkRect
.GetWidth() < aTextSiz
.Width() && !IsVerticalWriting())
823 // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
824 // else the alignment is wanted.
825 if(SDRTEXTHORZADJUST_BLOCK
== eHAdj
)
827 eHAdj
= SDRTEXTHORZADJUST_CENTER
;
831 if(aAnkRect
.GetHeight() < aTextSiz
.Height() && IsVerticalWriting())
833 // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
834 // else the alignment is wanted.
835 if(SDRTEXTVERTADJUST_BLOCK
== eVAdj
)
837 eVAdj
= SDRTEXTVERTADJUST_CENTER
;
842 if (eHAdj
==SDRTEXTHORZADJUST_CENTER
|| eHAdj
==SDRTEXTHORZADJUST_RIGHT
)
844 long nFreeWdt
=aAnkRect
.GetWidth()-aTextSiz
.Width();
845 if (eHAdj
==SDRTEXTHORZADJUST_CENTER
)
846 aTextPos
.X()+=nFreeWdt
/2;
847 if (eHAdj
==SDRTEXTHORZADJUST_RIGHT
)
848 aTextPos
.X()+=nFreeWdt
;
850 if (eVAdj
==SDRTEXTVERTADJUST_CENTER
|| eVAdj
==SDRTEXTVERTADJUST_BOTTOM
)
852 long nFreeHgt
=aAnkRect
.GetHeight()-aTextSiz
.Height();
853 if (eVAdj
==SDRTEXTVERTADJUST_CENTER
)
854 aTextPos
.Y()+=nFreeHgt
/2;
855 if (eVAdj
==SDRTEXTVERTADJUST_BOTTOM
)
856 aTextPos
.Y()+=nFreeHgt
;
858 if (aGeo
.nRotationAngle
!=0)
859 RotatePoint(aTextPos
,aAnkRect
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
862 *pAnchorRect
=aAnkRect
;
864 // rTextRect might not be correct in some cases at ContourFrame
865 rTextRect
=Rectangle(aTextPos
,aTextSiz
);
870 OutlinerParaObject
* SdrTextObj::GetEditOutlinerParaObject() const
872 OutlinerParaObject
* pPara
=NULL
;
873 if( HasTextImpl( pEdtOutl
) )
875 sal_Int32 nParaCount
= pEdtOutl
->GetParagraphCount();
876 pPara
= pEdtOutl
->CreateParaObject(0, nParaCount
);
881 void SdrTextObj::ImpSetCharStretching(SdrOutliner
& rOutliner
, const Size
& rTextSize
, const Size
& rShapeSize
, Fraction
& rFitXKorreg
)
883 OutputDevice
* pOut
= rOutliner
.GetRefDevice();
884 bool bNoStretching(false);
886 if(pOut
&& pOut
->GetOutDevType() == OUTDEV_PRINTER
)
888 // check whether CharStretching is possible at all
889 GDIMetaFile
* pMtf
= pOut
->GetConnectMetaFile();
890 OUString
aTestString(static_cast<sal_Unicode
>('J'));
892 if(pMtf
&& (!pMtf
->IsRecord() || pMtf
->IsPause()))
898 vcl::Font
aFontMerk(pOut
->GetFont());
899 vcl::Font
aTmpFont( OutputDevice::GetDefaultFont( DefaultFontType::SERIF
, LANGUAGE_SYSTEM
, GetDefaultFontFlags::OnlyOne
) );
901 aTmpFont
.SetSize(Size(0,100));
902 pOut
->SetFont(aTmpFont
);
903 Size
aSize1(pOut
->GetTextWidth(aTestString
), pOut
->GetTextHeight());
904 aTmpFont
.SetSize(Size(800,100));
905 pOut
->SetFont(aTmpFont
);
906 Size
aSize2(pOut
->GetTextWidth(aTestString
), pOut
->GetTextHeight());
907 pOut
->SetFont(aFontMerk
);
912 bNoStretching
= (aSize1
== aSize2
);
915 // Windows zooms the font proportionally when using Size(100,500),
916 // we don't like that.
917 if(aSize2
.Height() >= aSize1
.Height() * 2)
919 bNoStretching
= true;
923 unsigned nLoopCount
=0;
924 bool bNoMoreLoop
= false;
925 long nXDiff0
=0x7FFFFFFF;
926 long nWantWdt
=rShapeSize
.Width();
927 long nIsWdt
=rTextSize
.Width();
928 if (nIsWdt
==0) nIsWdt
=1;
930 long nWantHgt
=rShapeSize
.Height();
931 long nIsHgt
=rTextSize
.Height();
932 if (nIsHgt
==0) nIsHgt
=1;
934 long nXTolPl
=nWantWdt
/100; // tolerance: +1%
935 long nXTolMi
=nWantWdt
/25; // tolerance: -4%
936 long nXKorr
=nWantWdt
/20; // correction scale: 5%
938 long nX
=(nWantWdt
*100) /nIsWdt
; // calculate X stretching
939 long nY
=(nWantHgt
*100) /nIsHgt
; // calculate Y stretching
941 if (bNoStretching
) { // might only be possible proportionally
942 if (nX
>nY
) { nX
=nY
; bChkX
=false; }
946 while (nLoopCount
<5 && !bNoMoreLoop
) {
948 if (nX
<1) { nX
=1; bNoMoreLoop
= true; }
949 if (nX
>65535) { nX
=65535; bNoMoreLoop
= true; }
952 if (nY
<1) { nY
=1; bNoMoreLoop
= true; }
953 if (nY
>65535) { nY
=65535; bNoMoreLoop
= true; }
955 // exception, there is no text yet (horizontal case)
962 // exception, there is no text yet (vertical case)
969 rOutliner
.SetGlobalCharStretching((sal_uInt16
)nX
,(sal_uInt16
)nY
);
971 Size
aSiz(rOutliner
.CalcTextSize());
972 long nXDiff
=aSiz
.Width()-nWantWdt
;
973 rFitXKorreg
=Fraction(nWantWdt
,aSiz
.Width());
974 if (((nXDiff
>=nXTolMi
|| !bChkX
) && nXDiff
<=nXTolPl
) || nXDiff
==nXDiff0
) {
977 // correct stretching factors
979 long nDiv
=aSiz
.Width();
980 if (std::abs(nXDiff
)<=2*nXKorr
) {
981 if (nMul
>nDiv
) nDiv
+=(nMul
-nDiv
)/2; // but only add half of what we calculated,
982 else nMul
+=(nDiv
-nMul
)/2; // because the EditEngine calculates wrongly later on
985 if (bNoStretching
) nY
=nX
;
991 OUString
SdrTextObj::TakeObjNameSingul() const
997 case OBJ_OUTLINETEXT
:
999 aStr
= ImpGetResStr(STR_ObjNameSingulOUTLINETEXT
);
1003 case OBJ_TITLETEXT
:
1005 aStr
= ImpGetResStr(STR_ObjNameSingulTITLETEXT
);
1012 aStr
= ImpGetResStr(STR_ObjNameSingulTEXTLNK
);
1014 aStr
= ImpGetResStr(STR_ObjNameSingulTEXT
);
1019 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
1020 if(pOutlinerParaObject
&& eTextKind
!= OBJ_OUTLINETEXT
)
1022 // shouldn't currently cause any problems at OUTLINETEXT
1023 OUString
aStr2(comphelper::string::stripStart(pOutlinerParaObject
->GetTextObject().GetText(0), ' '));
1025 // avoid non expanded text portions in object name
1026 // (second condition is new)
1027 if(!aStr2
.isEmpty() && aStr2
.indexOf(sal_Unicode(255)) == -1)
1029 // space between ResStr and content text
1034 if(aStr2
.getLength() > 10)
1036 aStr2
= aStr2
.copy(0, 8);
1045 OUStringBuffer
sName(aStr
);
1047 OUString
aName(GetName());
1048 if (!aName
.isEmpty())
1052 sName
.append(aName
);
1056 return sName
.makeStringAndClear();
1059 OUString
SdrTextObj::TakeObjNamePlural() const
1062 switch (eTextKind
) {
1063 case OBJ_OUTLINETEXT
: sName
=ImpGetResStr(STR_ObjNamePluralOUTLINETEXT
); break;
1064 case OBJ_TITLETEXT
: sName
=ImpGetResStr(STR_ObjNamePluralTITLETEXT
); break;
1066 if (IsLinkedText()) {
1067 sName
=ImpGetResStr(STR_ObjNamePluralTEXTLNK
);
1069 sName
=ImpGetResStr(STR_ObjNamePluralTEXT
);
1076 SdrTextObj
* SdrTextObj::Clone() const
1078 return CloneHelper
< SdrTextObj
>();
1081 SdrTextObj
& SdrTextObj::operator=(const SdrTextObj
& rObj
)
1086 SdrObject::operator=(rObj
);
1088 maRect
= rObj
.maRect
;
1090 eTextKind
=rObj
.eTextKind
;
1091 bTextFrame
=rObj
.bTextFrame
;
1092 aTextSize
=rObj
.aTextSize
;
1093 bTextSizeDirty
=rObj
.bTextSizeDirty
;
1095 // Not all of the necessary parameters were copied yet.
1096 bNoShear
= rObj
.bNoShear
;
1097 bNoRotate
= rObj
.bNoRotate
;
1098 bNoMirror
= rObj
.bNoMirror
;
1099 bDisableAutoWidthOnDragging
= rObj
.bDisableAutoWidthOnDragging
;
1101 OutlinerParaObject
* pNewOutlinerParaObject
= 0;
1103 SdrText
* pText
= getActiveText();
1105 if( pText
&& rObj
.HasText() )
1107 const Outliner
* pEO
=rObj
.pEdtOutl
;
1110 pNewOutlinerParaObject
= pEO
->CreateParaObject();
1114 pNewOutlinerParaObject
= new OutlinerParaObject(*rObj
.getActiveText()->GetOutlinerParaObject());
1118 mpText
->SetOutlinerParaObject( pNewOutlinerParaObject
);
1119 ImpSetTextStyleSheetListeners();
1123 basegfx::B2DPolyPolygon
SdrTextObj::TakeXorPoly() const
1125 Polygon
aPol(maRect
);
1126 if (aGeo
.nShearAngle
!=0) ShearPoly(aPol
,maRect
.TopLeft(),aGeo
.nTan
);
1127 if (aGeo
.nRotationAngle
!=0) RotatePoly(aPol
,maRect
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
1129 basegfx::B2DPolyPolygon aRetval
;
1130 aRetval
.append(aPol
.getB2DPolygon());
1134 basegfx::B2DPolyPolygon
SdrTextObj::TakeContour() const
1136 basegfx::B2DPolyPolygon
aRetval(SdrAttrObj::TakeContour());
1138 // and now add the BoundRect of the text, if necessary
1139 if ( pModel
&& GetOutlinerParaObject() && !IsFontwork() && !IsContourTextFrame() )
1141 // using Clone()-Paint() strategy inside TakeContour() leaves a destroyed
1142 // SdrObject as pointer in DrawOutliner. Set *this again in fetching the outliner
1144 SdrOutliner
& rOutliner
=ImpGetDrawOutliner();
1148 TakeTextRect(rOutliner
,aR
,false,&aAnchor2
);
1150 bool bFitToSize(IsFitToSize());
1151 if (bFitToSize
) aR
=aAnchor2
;
1153 if (aGeo
.nRotationAngle
!=0) RotatePoly(aPol
,aR
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
1155 aRetval
.append(aPol
.getB2DPolygon());
1161 void SdrTextObj::RecalcSnapRect()
1163 if (aGeo
.nRotationAngle
!=0 || aGeo
.nShearAngle
!=0)
1165 Polygon
aPol(maRect
);
1166 if (aGeo
.nShearAngle
!=0) ShearPoly(aPol
,maRect
.TopLeft(),aGeo
.nTan
);
1167 if (aGeo
.nRotationAngle
!=0) RotatePoly(aPol
,maRect
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
1168 maSnapRect
=aPol
.GetBoundRect();
1170 maSnapRect
= maRect
;
1174 sal_uInt32
SdrTextObj::GetSnapPointCount() const
1179 Point
SdrTextObj::GetSnapPoint(sal_uInt32 i
) const
1183 case 0: aP
=maRect
.TopLeft(); break;
1184 case 1: aP
=maRect
.TopRight(); break;
1185 case 2: aP
=maRect
.BottomLeft(); break;
1186 case 3: aP
=maRect
.BottomRight(); break;
1187 default: aP
=maRect
.Center(); break;
1189 if (aGeo
.nShearAngle
!=0) ShearPoint(aP
,maRect
.TopLeft(),aGeo
.nTan
);
1190 if (aGeo
.nRotationAngle
!=0) RotatePoint(aP
,maRect
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
1194 void SdrTextObj::ImpCheckMasterCachable()
1196 bNotMasterCachable
=false;
1198 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
1200 if(!bNotVisibleAsMaster
&& pOutlinerParaObject
&& pOutlinerParaObject
->IsEditDoc() )
1202 const EditTextObject
& rText
= pOutlinerParaObject
->GetTextObject();
1203 bNotMasterCachable
=rText
.HasField(SvxPageField::StaticClassId());
1204 if( !bNotMasterCachable
)
1206 bNotMasterCachable
=rText
.HasField(SvxHeaderField::StaticClassId());
1207 if( !bNotMasterCachable
)
1209 bNotMasterCachable
=rText
.HasField(SvxFooterField::StaticClassId());
1210 if( !bNotMasterCachable
)
1212 bNotMasterCachable
=rText
.HasField(SvxDateTimeField::StaticClassId());
1219 // Extracted from ImpGetDrawOutliner()
1220 void SdrTextObj::ImpInitDrawOutliner( SdrOutliner
& rOutl
) const
1222 rOutl
.SetUpdateMode(false);
1223 sal_uInt16 nOutlinerMode
= OUTLINERMODE_OUTLINEOBJECT
;
1224 if ( !IsOutlText() )
1225 nOutlinerMode
= OUTLINERMODE_TEXTOBJECT
;
1226 rOutl
.Init( nOutlinerMode
);
1228 rOutl
.SetGlobalCharStretching(100,100);
1229 EEControlBits nStat
=rOutl
.GetControlWord();
1230 nStat
&= ~EEControlBits(EEControlBits::STRETCHING
|EEControlBits::AUTOPAGESIZE
);
1231 rOutl
.SetControlWord(nStat
);
1233 Size
aMaxSize(100000,100000);
1234 rOutl
.SetMinAutoPaperSize(aNullSize
);
1235 rOutl
.SetMaxAutoPaperSize(aMaxSize
);
1236 rOutl
.SetPaperSize(aMaxSize
);
1237 rOutl
.ClearPolygon();
1240 SdrOutliner
& SdrTextObj::ImpGetDrawOutliner() const
1242 SdrOutliner
& rOutl
=pModel
->GetDrawOutliner(this);
1244 // Code extracted to ImpInitDrawOutliner()
1245 ImpInitDrawOutliner( rOutl
);
1250 // Extracted from Paint()
1251 void SdrTextObj::ImpSetupDrawOutlinerForPaint( bool bContourFrame
,
1252 SdrOutliner
& rOutliner
,
1253 Rectangle
& rTextRect
,
1254 Rectangle
& rAnchorRect
,
1255 Rectangle
& rPaintRect
,
1256 Fraction
& rFitXKorreg
) const
1260 // FitToSize can't be used together with ContourFrame for now
1261 if (IsFitToSize() || IsAutoFit())
1263 EEControlBits nStat
=rOutliner
.GetControlWord();
1264 nStat
|=EEControlBits::STRETCHING
|EEControlBits::AUTOPAGESIZE
;
1265 rOutliner
.SetControlWord(nStat
);
1268 rOutliner
.SetFixedCellHeight(static_cast<const SdrTextFixedCellHeightItem
&>(GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT
)).GetValue());
1269 TakeTextRect(rOutliner
, rTextRect
, false, &rAnchorRect
);
1270 rPaintRect
= rTextRect
;
1274 // FitToSize can't be used together with ContourFrame for now
1277 ImpSetCharStretching(rOutliner
,rTextRect
.GetSize(),rAnchorRect
.GetSize(),rFitXKorreg
);
1278 rPaintRect
=rAnchorRect
;
1280 else if (IsAutoFit())
1282 ImpAutoFitText(rOutliner
);
1287 void SdrTextObj::ImpAutoFitText( SdrOutliner
& rOutliner
) const
1289 const Size aShapeSize
=GetSnapRect().GetSize();
1290 ImpAutoFitText( rOutliner
,
1291 Size(aShapeSize
.Width()-GetTextLeftDistance()-GetTextRightDistance(),
1292 aShapeSize
.Height()-GetTextUpperDistance()-GetTextLowerDistance()),
1293 IsVerticalWriting() );
1296 void SdrTextObj::ImpAutoFitText( SdrOutliner
& rOutliner
, const Size
& rTextSize
, bool bIsVerticalWriting
)
1298 // EditEngine formatting is unstable enough for
1299 // line-breaking text that we need some more samples
1301 // loop early-exits if we detect an already attained value
1302 sal_uInt16 nMinStretchX
=0, nMinStretchY
=0;
1303 sal_uInt16 aOldStretchXVals
[]={0,0,0,0,0,0,0,0,0,0};
1304 const size_t aStretchArySize
=SAL_N_ELEMENTS(aOldStretchXVals
);
1305 for(unsigned int i
=0; i
<aStretchArySize
; ++i
)
1307 const Size aCurrTextSize
= rOutliner
.CalcTextSizeNTP();
1308 double fFactor(1.0);
1309 if( bIsVerticalWriting
)
1310 fFactor
= double(rTextSize
.Width())/aCurrTextSize
.Width();
1312 fFactor
= double(rTextSize
.Height())/aCurrTextSize
.Height();
1313 // fFactor scales in both x and y directions
1314 // - this is fine for bulleted words
1315 // - but it scales too much for a long paragraph
1316 // - taking sqrt scales long paragraphs the best
1317 // - bulleted words will have to go through more iterations
1318 fFactor
= std::sqrt(fFactor
);
1320 sal_uInt16 nCurrStretchX
, nCurrStretchY
;
1321 rOutliner
.GetGlobalCharStretching(nCurrStretchX
, nCurrStretchY
);
1323 if (fFactor
>= 1.0 )
1325 // resulting text area fits into available shape rect -
1326 // err on the larger stretching, to optimally fill area
1327 nMinStretchX
= std::max(nMinStretchX
,nCurrStretchX
);
1328 nMinStretchY
= std::max(nMinStretchY
,nCurrStretchY
);
1331 aOldStretchXVals
[i
] = nCurrStretchX
;
1332 if( std::find(aOldStretchXVals
, aOldStretchXVals
+i
, nCurrStretchX
) != aOldStretchXVals
+i
)
1333 break; // same value already attained once; algo is looping, exit
1335 if (fFactor
< 1.0 || (fFactor
>= 1.0 && nCurrStretchX
!= 100))
1337 nCurrStretchX
= sal::static_int_cast
<sal_uInt16
>(nCurrStretchX
*fFactor
);
1338 nCurrStretchY
= sal::static_int_cast
<sal_uInt16
>(nCurrStretchY
*fFactor
);
1339 rOutliner
.SetGlobalCharStretching(std::min(sal_uInt16(100),nCurrStretchX
),
1340 std::min(sal_uInt16(100),nCurrStretchY
));
1341 OSL_TRACE("SdrTextObj::onEditOutlinerStatusEvent(): zoom is %d", nCurrStretchX
);
1345 OSL_TRACE("---- SdrTextObj::onEditOutlinerStatusEvent(): final zoom is %d ----", nMinStretchX
);
1346 rOutliner
.SetGlobalCharStretching(std::min(sal_uInt16(100),nMinStretchX
),
1347 std::min(sal_uInt16(100),nMinStretchY
));
1350 void SdrTextObj::SetupOutlinerFormatting( SdrOutliner
& rOutl
, Rectangle
& rPaintRect
) const
1352 ImpInitDrawOutliner( rOutl
);
1353 UpdateOutlinerFormatting( rOutl
, rPaintRect
);
1356 void SdrTextObj::UpdateOutlinerFormatting( SdrOutliner
& rOutl
, Rectangle
& rPaintRect
) const
1358 Rectangle aTextRect
;
1359 Rectangle aAnchorRect
;
1360 Fraction
aFitXKorreg(1,1);
1362 bool bContourFrame
=IsContourTextFrame();
1366 MapMode
aMapMode(GetModel()->GetScaleUnit(), Point(0,0),
1367 GetModel()->GetScaleFraction(),
1368 GetModel()->GetScaleFraction());
1369 rOutl
.SetRefMapMode(aMapMode
);
1372 ImpSetupDrawOutlinerForPaint( bContourFrame
, rOutl
, aTextRect
, aAnchorRect
, rPaintRect
, aFitXKorreg
);
1377 OutlinerParaObject
* SdrTextObj::GetOutlinerParaObject() const
1379 SdrText
* pText
= getActiveText();
1381 return pText
->GetOutlinerParaObject();
1386 void SdrTextObj::NbcSetOutlinerParaObject(OutlinerParaObject
* pTextObject
)
1388 NbcSetOutlinerParaObjectForText( pTextObject
, getActiveText() );
1391 void SdrTextObj::NbcSetOutlinerParaObjectForText( OutlinerParaObject
* pTextObject
, SdrText
* pText
)
1394 pText
->SetOutlinerParaObject( pTextObject
);
1396 if (pText
&& pText
->GetOutlinerParaObject())
1398 SvxWritingModeItem
aWritingMode(pText
->GetOutlinerParaObject()->IsVertical()
1399 ? com::sun::star::text::WritingMode_TB_RL
1400 : com::sun::star::text::WritingMode_LR_TB
,
1401 SDRATTR_TEXTDIRECTION
);
1402 GetProperties().SetObjectItemDirect(aWritingMode
);
1406 if (IsTextFrame() && (IsAutoGrowHeight() || IsAutoGrowWidth()))
1407 { // adapt text frame!
1408 NbcAdjustTextFrameWidthAndHeight();
1412 // the SnapRect keeps its size
1413 SetRectsDirty(true);
1416 // always invalidate BoundRect on change
1417 SetBoundRectDirty();
1420 ImpSetTextStyleSheetListeners();
1421 ImpCheckMasterCachable();
1424 void SdrTextObj::NbcReformatText()
1426 SdrText
* pText
= getActiveText();
1427 if( pText
&& pText
->GetOutlinerParaObject() )
1429 pText
->ReformatText();
1432 NbcAdjustTextFrameWidthAndHeight();
1436 // the SnapRect keeps its size
1437 SetBoundRectDirty();
1438 SetRectsDirty(true);
1443 // Necessary here since we have no compare operator at the outliner
1444 // para object which may detect changes regarding the combination
1445 // of outliner para data and configuration (e.g., change of
1446 // formatting of text numerals)
1447 GetViewContact().flushViewObjectContacts(false);
1451 void SdrTextObj::ReformatText()
1453 if(GetOutlinerParaObject())
1455 Rectangle aBoundRect0
;
1456 if (pUserCall
!=NULL
)
1457 aBoundRect0
=GetLastBoundRect();
1461 BroadcastObjectChange();
1462 SendUserCall(SDRUSERCALL_RESIZE
,aBoundRect0
);
1466 SdrObjGeoData
* SdrTextObj::NewGeoData() const
1468 return new SdrTextObjGeoData
;
1471 void SdrTextObj::SaveGeoData(SdrObjGeoData
& rGeo
) const
1473 SdrAttrObj::SaveGeoData(rGeo
);
1474 SdrTextObjGeoData
& rTGeo
=static_cast<SdrTextObjGeoData
&>(rGeo
);
1475 rTGeo
.aRect
= maRect
;
1479 void SdrTextObj::RestGeoData(const SdrObjGeoData
& rGeo
)
1480 { // RectsDirty is called by SdrObject
1481 SdrAttrObj::RestGeoData(rGeo
);
1482 const SdrTextObjGeoData
& rTGeo
=static_cast<const SdrTextObjGeoData
&>(rGeo
);
1483 NbcSetLogicRect(rTGeo
.aRect
);
1488 SdrFitToSizeType
SdrTextObj::GetFitToSize() const
1490 SdrFitToSizeType eType
= SDRTEXTFIT_NONE
;
1492 if(!IsAutoGrowWidth())
1493 eType
= static_cast<const SdrTextFitToSizeTypeItem
&>(GetObjectItem(SDRATTR_TEXT_FITTOSIZE
)).GetValue();
1498 const Rectangle
& SdrTextObj::GetGeoRect() const
1503 void SdrTextObj::ForceOutlinerParaObject()
1505 SdrText
* pText
= getActiveText();
1506 if( pText
&& (pText
->GetOutlinerParaObject() == 0) )
1508 sal_uInt16 nOutlMode
= OUTLINERMODE_TEXTOBJECT
;
1509 if( IsTextFrame() && eTextKind
== OBJ_OUTLINETEXT
)
1510 nOutlMode
= OUTLINERMODE_OUTLINEOBJECT
;
1512 pText
->ForceOutlinerParaObject( nOutlMode
);
1516 bool SdrTextObj::IsVerticalWriting() const
1520 return pEdtOutl
->IsVertical();
1523 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
1524 if(pOutlinerParaObject
)
1526 return pOutlinerParaObject
->IsVertical();
1532 void SdrTextObj::SetVerticalWriting(bool bVertical
)
1534 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
1535 if( !pOutlinerParaObject
&& bVertical
)
1537 // we only need to force a outliner para object if the default of
1538 // horizontal text is changed
1539 ForceOutlinerParaObject();
1540 pOutlinerParaObject
= GetOutlinerParaObject();
1543 if( pOutlinerParaObject
&& (pOutlinerParaObject
->IsVertical() != (bool)bVertical
) )
1545 // get item settings
1546 const SfxItemSet
& rSet
= GetObjectItemSet();
1547 bool bAutoGrowWidth
= static_cast<const SdrOnOffItem
&>(rSet
.Get(SDRATTR_TEXT_AUTOGROWWIDTH
)).GetValue();
1548 bool bAutoGrowHeight
= static_cast<const SdrOnOffItem
&>(rSet
.Get(SDRATTR_TEXT_AUTOGROWHEIGHT
)).GetValue();
1550 // Also exchange hor/ver adjust items
1551 SdrTextHorzAdjust eHorz
= static_cast<const SdrTextHorzAdjustItem
&>(rSet
.Get(SDRATTR_TEXT_HORZADJUST
)).GetValue();
1552 SdrTextVertAdjust eVert
= static_cast<const SdrTextVertAdjustItem
&>(rSet
.Get(SDRATTR_TEXT_VERTADJUST
)).GetValue();
1554 // rescue object size
1555 Rectangle aObjectRect
= GetSnapRect();
1557 // prepare ItemSet to set exchanged width and height items
1558 SfxItemSet
aNewSet(*rSet
.GetPool(),
1559 SDRATTR_TEXT_AUTOGROWHEIGHT
, SDRATTR_TEXT_AUTOGROWHEIGHT
,
1560 // Expanded item ranges to also support hor and ver adjust.
1561 SDRATTR_TEXT_VERTADJUST
, SDRATTR_TEXT_VERTADJUST
,
1562 SDRATTR_TEXT_AUTOGROWWIDTH
, SDRATTR_TEXT_HORZADJUST
,
1566 aNewSet
.Put(makeSdrTextAutoGrowWidthItem(bAutoGrowHeight
));
1567 aNewSet
.Put(makeSdrTextAutoGrowHeightItem(bAutoGrowWidth
));
1569 // Exchange horz and vert adjusts
1572 case SDRTEXTVERTADJUST_TOP
: aNewSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT
)); break;
1573 case SDRTEXTVERTADJUST_CENTER
: aNewSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER
)); break;
1574 case SDRTEXTVERTADJUST_BOTTOM
: aNewSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT
)); break;
1575 case SDRTEXTVERTADJUST_BLOCK
: aNewSet
.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK
)); break;
1579 case SDRTEXTHORZADJUST_LEFT
: aNewSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM
)); break;
1580 case SDRTEXTHORZADJUST_CENTER
: aNewSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER
)); break;
1581 case SDRTEXTHORZADJUST_RIGHT
: aNewSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP
)); break;
1582 case SDRTEXTHORZADJUST_BLOCK
: aNewSet
.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK
)); break;
1585 SetObjectItemSet(aNewSet
);
1587 pOutlinerParaObject
= GetOutlinerParaObject();
1588 if( pOutlinerParaObject
)
1590 // set ParaObject orientation accordingly
1591 pOutlinerParaObject
->SetVertical(bVertical
);
1594 // restore object size
1595 SetSnapRect(aObjectRect
);
1601 // transformation interface for StarOfficeAPI. This implements support for
1602 // homogeneous 3x3 matrices containing the transformation of the SdrObject. At the
1603 // moment it contains a shearX, rotation and translation, but for setting all linear
1604 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
1607 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
1608 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
1609 bool SdrTextObj::TRGetBaseGeometry(basegfx::B2DHomMatrix
& rMatrix
, basegfx::B2DPolyPolygon
& /*rPolyPolygon*/) const
1611 // get turn and shear
1612 double fRotate
= (aGeo
.nRotationAngle
/ 100.0) * F_PI180
;
1613 double fShearX
= (aGeo
.nShearAngle
/ 100.0) * F_PI180
;
1615 // get aRect, this is the unrotated snaprect
1616 Rectangle
aRectangle(maRect
);
1618 // fill other values
1619 basegfx::B2DTuple
aScale(aRectangle
.GetWidth(), aRectangle
.GetHeight());
1620 basegfx::B2DTuple
aTranslate(aRectangle
.Left(), aRectangle
.Top());
1622 // position maybe relative to anchorpos, convert
1623 if( pModel
&& pModel
->IsWriter() )
1625 if(GetAnchorPos().X() || GetAnchorPos().Y())
1627 aTranslate
-= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1631 // force MapUnit to 100th mm
1632 const SfxMapUnit
eMapUnit(GetObjectMapUnit());
1633 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
1637 case SFX_MAPUNIT_TWIP
:
1640 aTranslate
.setX(ImplTwipsToMM(aTranslate
.getX()));
1641 aTranslate
.setY(ImplTwipsToMM(aTranslate
.getY()));
1644 aScale
.setX(ImplTwipsToMM(aScale
.getX()));
1645 aScale
.setY(ImplTwipsToMM(aScale
.getY()));
1651 OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
1657 rMatrix
= basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
1659 basegfx::fTools::equalZero(fShearX
) ? 0.0 : tan(fShearX
),
1660 basegfx::fTools::equalZero(fRotate
) ? 0.0 : -fRotate
,
1666 // sets the base geometry of the object using infos contained in the homogeneous 3x3 matrix.
1667 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
1668 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
1669 void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix
& rMatrix
, const basegfx::B2DPolyPolygon
& /*rPolyPolygon*/)
1672 basegfx::B2DTuple aScale
;
1673 basegfx::B2DTuple aTranslate
;
1674 double fRotate(0.0);
1675 double fShearX(0.0);
1676 rMatrix
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
1678 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
1679 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
1680 if(basegfx::fTools::less(aScale
.getX(), 0.0) && basegfx::fTools::less(aScale
.getY(), 0.0))
1682 aScale
.setX(fabs(aScale
.getX()));
1683 aScale
.setY(fabs(aScale
.getY()));
1684 fRotate
= fmod(fRotate
+ F_PI
, F_2PI
);
1687 // reset object shear and rotations
1688 aGeo
.nRotationAngle
= 0;
1689 aGeo
.RecalcSinCos();
1690 aGeo
.nShearAngle
= 0;
1693 // force metric to pool metric
1694 const SfxMapUnit
eMapUnit(GetObjectMapUnit());
1695 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
1699 case SFX_MAPUNIT_TWIP
:
1702 aTranslate
.setX(ImplMMToTwips(aTranslate
.getX()));
1703 aTranslate
.setY(ImplMMToTwips(aTranslate
.getY()));
1706 aScale
.setX(ImplMMToTwips(aScale
.getX()));
1707 aScale
.setY(ImplMMToTwips(aScale
.getY()));
1713 OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
1718 // if anchor is used, make position relative to it
1719 if( pModel
&& pModel
->IsWriter() )
1721 if(GetAnchorPos().X() || GetAnchorPos().Y())
1723 aTranslate
+= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1727 // build and set BaseRect (use scale)
1728 Point aPoint
= Point();
1729 Size
aSize(FRound(aScale
.getX()), FRound(aScale
.getY()));
1730 Rectangle
aBaseRect(aPoint
, aSize
);
1731 SetSnapRect(aBaseRect
);
1734 if(!basegfx::fTools::equalZero(fShearX
))
1737 aGeoStat
.nShearAngle
= FRound((atan(fShearX
) / F_PI180
) * 100.0);
1738 aGeoStat
.RecalcTan();
1739 Shear(Point(), aGeoStat
.nShearAngle
, aGeoStat
.nTan
, false);
1743 if(!basegfx::fTools::equalZero(fRotate
))
1748 // fRotate is matematically correct, but aGeoStat.nRotationAngle is
1749 // mirrored -> mirror value here
1750 aGeoStat
.nRotationAngle
= NormAngle360(FRound(-fRotate
/ F_PI18000
));
1751 aGeoStat
.RecalcSinCos();
1752 Rotate(Point(), aGeoStat
.nRotationAngle
, aGeoStat
.nSin
, aGeoStat
.nCos
);
1756 if(!aTranslate
.equalZero())
1758 Move(Size(FRound(aTranslate
.getX()), FRound(aTranslate
.getY())));
1762 bool SdrTextObj::IsReallyEdited() const
1764 return pEdtOutl
&& pEdtOutl
->IsModified();
1767 // moved inlines here form hxx
1769 long SdrTextObj::GetEckenradius() const
1771 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_ECKENRADIUS
)).GetValue();
1774 long SdrTextObj::GetMinTextFrameHeight() const
1776 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEHEIGHT
)).GetValue();
1779 long SdrTextObj::GetMaxTextFrameHeight() const
1781 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEHEIGHT
)).GetValue();
1784 long SdrTextObj::GetMinTextFrameWidth() const
1786 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEWIDTH
)).GetValue();
1789 long SdrTextObj::GetMaxTextFrameWidth() const
1791 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEWIDTH
)).GetValue();
1794 bool SdrTextObj::IsFontwork() const
1796 return !bTextFrame
// Default is FALSE
1797 && static_cast<const XFormTextStyleItem
&>(GetObjectItemSet().Get(XATTR_FORMTXTSTYLE
)).GetValue() != XFT_NONE
;
1800 bool SdrTextObj::IsHideContour() const
1802 return !bTextFrame
// Default is: no, don't HideContour; HideContour not together with TextFrames
1803 && static_cast<const XFormTextHideFormItem
&>(GetObjectItemSet().Get(XATTR_FORMTXTHIDEFORM
)).GetValue();
1806 bool SdrTextObj::IsContourTextFrame() const
1808 return !bTextFrame
// ContourFrame not together with normal TextFrames
1809 && static_cast<const SdrOnOffItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_CONTOURFRAME
)).GetValue();
1812 long SdrTextObj::GetTextLeftDistance() const
1814 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_LEFTDIST
)).GetValue();
1817 long SdrTextObj::GetTextRightDistance() const
1819 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_RIGHTDIST
)).GetValue();
1822 long SdrTextObj::GetTextUpperDistance() const
1824 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_UPPERDIST
)).GetValue();
1827 long SdrTextObj::GetTextLowerDistance() const
1829 return static_cast<const SdrMetricItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_LOWERDIST
)).GetValue();
1832 SdrTextAniKind
SdrTextObj::GetTextAniKind() const
1834 return static_cast<const SdrTextAniKindItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_ANIKIND
)).GetValue();
1837 SdrTextAniDirection
SdrTextObj::GetTextAniDirection() const
1839 return static_cast<const SdrTextAniDirectionItem
&>(GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION
)).GetValue();
1842 // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a
1843 // painting rectangle. Rotation is excluded from the returned values.
1844 GDIMetaFile
* SdrTextObj::GetTextScrollMetaFileAndRectangle(
1845 Rectangle
& rScrollRectangle
, Rectangle
& rPaintRectangle
)
1847 GDIMetaFile
* pRetval
= 0L;
1848 SdrOutliner
& rOutliner
= ImpGetDrawOutliner();
1849 Rectangle aTextRect
;
1850 Rectangle aAnchorRect
;
1851 Rectangle aPaintRect
;
1852 Fraction
aFitXKorreg(1,1);
1853 bool bContourFrame(IsContourTextFrame());
1855 // get outliner set up. To avoid getting a somehow rotated MetaFile,
1856 // temporarily disable object rotation.
1857 sal_Int32
nAngle(aGeo
.nRotationAngle
);
1858 aGeo
.nRotationAngle
= 0L;
1859 ImpSetupDrawOutlinerForPaint( bContourFrame
, rOutliner
, aTextRect
, aAnchorRect
, aPaintRect
, aFitXKorreg
);
1860 aGeo
.nRotationAngle
= nAngle
;
1862 Rectangle
aScrollFrameRect(aPaintRect
);
1863 const SfxItemSet
& rSet
= GetObjectItemSet();
1864 SdrTextAniDirection eDirection
= static_cast<const SdrTextAniDirectionItem
&>(rSet
.Get(SDRATTR_TEXT_ANIDIRECTION
)).GetValue();
1866 if(SDRTEXTANI_LEFT
== eDirection
|| SDRTEXTANI_RIGHT
== eDirection
)
1868 aScrollFrameRect
.Left() = aAnchorRect
.Left();
1869 aScrollFrameRect
.Right() = aAnchorRect
.Right();
1872 if(SDRTEXTANI_UP
== eDirection
|| SDRTEXTANI_DOWN
== eDirection
)
1874 aScrollFrameRect
.Top() = aAnchorRect
.Top();
1875 aScrollFrameRect
.Bottom() = aAnchorRect
.Bottom();
1878 // create the MetaFile
1879 pRetval
= new GDIMetaFile
;
1880 ScopedVclPtrInstance
< VirtualDevice
> pBlackHole
;
1881 pBlackHole
->EnableOutput(false);
1882 pRetval
->Record(pBlackHole
);
1883 Point aPaintPos
= aPaintRect
.TopLeft();
1885 rOutliner
.Draw(pBlackHole
, aPaintPos
);
1888 pRetval
->WindStart();
1890 // return PaintRectanglePixel and pRetval;
1891 rScrollRectangle
= aScrollFrameRect
;
1892 rPaintRectangle
= aPaintRect
;
1897 // Access to TextAnimationAllowed flag
1898 bool SdrTextObj::IsAutoFit() const
1900 return GetFitToSize()==SDRTEXTFIT_AUTOFIT
;
1903 bool SdrTextObj::IsFitToSize() const
1905 const SdrFitToSizeType eFit
=GetFitToSize();
1906 return (eFit
==SDRTEXTFIT_PROPORTIONAL
|| eFit
==SDRTEXTFIT_ALLLINES
);
1909 void SdrTextObj::SetTextAnimationAllowed(bool bNew
)
1911 if(mbTextAnimationAllowed
!= bNew
)
1913 mbTextAnimationAllowed
= bNew
;
1918 /** called from the SdrObjEditView during text edit when the status of the edit outliner changes */
1919 void SdrTextObj::onEditOutlinerStatusEvent( EditStatus
* pEditStatus
)
1921 const EditStatusFlags nStat
= pEditStatus
->GetStatusWord();
1922 const bool bGrowX
= bool(nStat
& EditStatusFlags::TEXTWIDTHCHANGED
);
1923 const bool bGrowY
= bool(nStat
& EditStatusFlags::TEXTHEIGHTCHANGED
);
1924 if(bTextFrame
&& (bGrowX
|| bGrowY
))
1926 if ((bGrowX
&& IsAutoGrowWidth()) || (bGrowY
&& IsAutoGrowHeight()))
1928 AdjustTextFrameWidthAndHeight();
1930 else if (IsAutoFit() && !mbInDownScale
)
1933 mbInDownScale
= true;
1935 // sucks that we cannot disable paints via
1936 // pEdtOutl->SetUpdateMode(FALSE) - but EditEngine skips
1937 // formatting as well, then.
1938 ImpAutoFitText(*pEdtOutl
);
1939 mbInDownScale
= false;
1944 /** returns the currently active text. */
1945 SdrText
* SdrTextObj::getActiveText() const
1948 return getText( 0 );
1953 /** returns the nth available text. */
1954 SdrText
* SdrTextObj::getText( sal_Int32 nIndex
) const
1959 const_cast< SdrTextObj
* >(this)->mpText
= new SdrText( *(const_cast< SdrTextObj
* >(this)) );
1968 /** returns the number of texts available for this object. */
1969 sal_Int32
SdrTextObj::getTextCount() const
1974 /** changes the current active text */
1975 void SdrTextObj::setActiveText( sal_Int32
/*nIndex*/ )
1979 /** returns the index of the text that contains the given point or -1 */
1980 sal_Int32
SdrTextObj::CheckTextHit(const Point
& /*rPnt*/) const
1985 void SdrTextObj::SetObjectItemNoBroadcast(const SfxPoolItem
& rItem
)
1987 static_cast< sdr::properties::TextProperties
& >(GetProperties()).SetObjectItemNoBroadcast(rItem
);
1992 // The concept of the text object:
1993 // ~~~~~~~~~~~~~~~~~~~~~~~~
1994 // Attributes/Variations:
1995 // - bool text frame / graphics object with caption
1996 // - bool FontWork (if it is not a text frame and not a ContourTextFrame)
1997 // - bool ContourTextFrame (if it is not a text frame and not Fontwork)
1998 // - long rotation angle (if it is not FontWork)
1999 // - long text frame margins (if it is not FontWork)
2000 // - bool FitToSize (if it is not FontWork)
2001 // - bool AutoGrowingWidth/Height (if it is not FitToSize and not FontWork)
2002 // - long Min/MaxFrameWidth/Height (if AutoGrowingWidth/Height)
2003 // - enum horizontal text anchoring left,center,right,justify/block,Stretch(ni)
2004 // - enum vertical text anchoring top, middle, bottom, block, stretch(ni)
2005 // - enum ticker text (if it is not FontWork)
2007 // Every derived object is either a text frame (bTextFrame=true)
2008 // or a drawing object with a caption (bTextFrame=false).
2010 // Default anchoring for text frames:
2011 // SDRTEXTHORZADJUST_BLOCK, SDRTEXTVERTADJUST_TOP
2012 // = static Pool defaults
2013 // Default anchoring for drawing objects with a caption:
2014 // SDRTEXTHORZADJUST_CENTER, SDRTEXTVERTADJUST_CENTER
2015 // via "hard" attribution of SdrAttrObj
2017 // Every object derived from SdrTextObj must return an "UnrotatedSnapRect"
2018 // (->TakeUnrotatedSnapRect()) (the reference point for the rotation is the top
2019 // left of the rectangle (aGeo.nRotationAngle)) which is the basis for anchoring
2020 // text. We then subtract the text frame margins from this rectangle, as a re-
2021 // sult we get the anchoring area (->TakeTextAnchorRect()). Within this area, we
2022 // calculate the anchoring point and the painting area, depending on the hori-
2023 // zontal and vertical adjustment of the text (SdrTextVertAdjust,
2024 // SdrTextHorzAdjust).
2025 // In the case of drawing objects with a caption the painting area might well
2026 // be larger than the anchoring area, for text frames on the other hand, it is
2027 // always of the same or a smaller size (except when there are negative text
2030 // FitToSize takes priority over text anchoring and AutoGrowHeight/Width. When
2031 // FitToSize is turned on, the painting area is always equal to the anchoring
2032 // area. Additionally, FitToSize doesn't allow automatic line breaks.
2034 // ContourTextFrame:
2035 // - long rotation angle
2036 // - long text frame margins (maybe later)
2037 // - bool FitToSize (maybe later)
2038 // - bool AutoGrowingWidth/Height (maybe much later)
2039 // - long Min/MaxFrameWidth/Height (maybe much later)
2040 // - enum horizontal text anchoring (maybe later, for now: left, centered)
2041 // - enum vertical text anchoring (maybe later, for now: top)
2042 // - enum ticker text (maybe later, maybe even with correct clipping)
2044 // When making changes, check these:
2049 // - Printing, Saving, Painting in neighboring View while editing
2050 // - ModelChanged (e. g. through a neighboring View or rulers) while editing
2051 // - FillColorChanged while editin
2052 // - and many more...
2056 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */