1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3efeef26fSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist * or more contributor license agreements. See the NOTICE file
5efeef26fSAndrew Rist * distributed with this work for additional information
6efeef26fSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7efeef26fSAndrew Rist * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11efeef26fSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13efeef26fSAndrew Rist * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist * software distributed under the License is distributed on an
15efeef26fSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist * KIND, either express or implied. See the License for the
17efeef26fSAndrew Rist * specific language governing permissions and limitations
18efeef26fSAndrew Rist * under the License.
19cdf0e10cSrcweir *
20efeef26fSAndrew Rist *************************************************************/
21efeef26fSAndrew Rist
22efeef26fSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include <hintids.hxx>
29cdf0e10cSrcweir
30cdf0e10cSrcweir #include <com/sun/star/i18n/ScriptType.hdl>
31cdf0e10cSrcweir #include <vcl/graph.hxx>
32cdf0e10cSrcweir #include <editeng/brshitem.hxx>
33cdf0e10cSrcweir #include <vcl/metric.hxx>
34cdf0e10cSrcweir #include <vcl/outdev.hxx>
35cdf0e10cSrcweir #include <viewopt.hxx> // SwViewOptions
36cdf0e10cSrcweir #include <txtcfg.hxx>
37cdf0e10cSrcweir #include <SwPortionHandler.hxx>
38cdf0e10cSrcweir #include <porlay.hxx>
39cdf0e10cSrcweir #include <porfld.hxx>
40cdf0e10cSrcweir #include <inftxt.hxx>
41cdf0e10cSrcweir #include <blink.hxx> // pBlink
42cdf0e10cSrcweir #include <frmtool.hxx> // DrawGraphic
43cdf0e10cSrcweir #include <viewsh.hxx>
44cdf0e10cSrcweir #include <docsh.hxx>
45cdf0e10cSrcweir #include <doc.hxx>
46cdf0e10cSrcweir #include "rootfrm.hxx"
47cdf0e10cSrcweir #include <breakit.hxx>
48cdf0e10cSrcweir #include <porrst.hxx>
49cdf0e10cSrcweir #include <porftn.hxx> // SwFtnPortion
50cdf0e10cSrcweir #include <accessibilityoptions.hxx>
51cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
52cdf0e10cSrcweir #include <unicode/ubidi.h>
53cdf0e10cSrcweir
54cdf0e10cSrcweir using namespace ::com::sun::star;
55cdf0e10cSrcweir
56cdf0e10cSrcweir /*************************************************************************
57cdf0e10cSrcweir * class SwFldPortion
58cdf0e10cSrcweir *************************************************************************/
59cdf0e10cSrcweir
Compress()60cdf0e10cSrcweir SwLinePortion *SwFldPortion::Compress()
61cdf0e10cSrcweir { return (GetLen() || aExpand.Len() || SwLinePortion::Compress()) ? this : 0; }
62cdf0e10cSrcweir
Clone(const XubString & rExpand) const63cdf0e10cSrcweir SwFldPortion *SwFldPortion::Clone( const XubString &rExpand ) const
64cdf0e10cSrcweir {
65cdf0e10cSrcweir SwFont *pNewFnt;
66cdf0e10cSrcweir if( 0 != ( pNewFnt = pFnt ) )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir pNewFnt = new SwFont( *pFnt );
69cdf0e10cSrcweir }
70cdf0e10cSrcweir SwFldPortion* pClone = new SwFldPortion( rExpand, pNewFnt, bPlaceHolder );
71cdf0e10cSrcweir pClone->SetNextOffset( nNextOffset );
72cdf0e10cSrcweir pClone->m_bNoLength = this->m_bNoLength;
73cdf0e10cSrcweir return pClone;
74cdf0e10cSrcweir }
75cdf0e10cSrcweir
TakeNextOffset(const SwFldPortion * pFld)76cdf0e10cSrcweir void SwFldPortion::TakeNextOffset( const SwFldPortion* pFld )
77cdf0e10cSrcweir {
78cdf0e10cSrcweir ASSERT( pFld, "TakeNextOffset: Missing Source" );
79cdf0e10cSrcweir nNextOffset = pFld->GetNextOffset();
80cdf0e10cSrcweir aExpand.Erase( 0, nNextOffset );
81cdf0e10cSrcweir bFollow = sal_True;
82cdf0e10cSrcweir }
83cdf0e10cSrcweir
SwFldPortion(const XubString & rExpand,SwFont * pFont,sal_Bool bPlaceHold)84cdf0e10cSrcweir SwFldPortion::SwFldPortion( const XubString &rExpand, SwFont *pFont, sal_Bool bPlaceHold )
85cdf0e10cSrcweir : aExpand(rExpand), pFnt(pFont), nNextOffset(0), nNextScriptChg(STRING_LEN), nViewWidth(0),
86cdf0e10cSrcweir bFollow( sal_False ), bHasFollow( sal_False ), bPlaceHolder( bPlaceHold )
87cdf0e10cSrcweir , m_bNoLength( sal_False )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir SetWhichPor( POR_FLD );
90ca62e2c2SSteve Yin m_nAttrFldType = 0;
91cdf0e10cSrcweir }
92cdf0e10cSrcweir
SwFldPortion(const SwFldPortion & rFld)93cdf0e10cSrcweir SwFldPortion::SwFldPortion( const SwFldPortion& rFld )
94cdf0e10cSrcweir : SwExpandPortion( rFld ),
95cdf0e10cSrcweir aExpand( rFld.GetExp() ),
96cdf0e10cSrcweir nNextOffset( rFld.GetNextOffset() ),
97cdf0e10cSrcweir nNextScriptChg( rFld.GetNextScriptChg() ),
98cdf0e10cSrcweir bFollow( rFld.IsFollow() ),
99cdf0e10cSrcweir bLeft( rFld.IsLeft() ),
100cdf0e10cSrcweir bHide( rFld.IsHide() ),
101cdf0e10cSrcweir bCenter( rFld.IsCenter() ),
102cdf0e10cSrcweir bHasFollow( rFld.HasFollow() ),
103cdf0e10cSrcweir bPlaceHolder( rFld.bPlaceHolder )
104cdf0e10cSrcweir , m_bNoLength( rFld.m_bNoLength )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir if ( rFld.HasFont() )
107cdf0e10cSrcweir pFnt = new SwFont( *rFld.GetFont() );
108cdf0e10cSrcweir else
109cdf0e10cSrcweir pFnt = 0;
110cdf0e10cSrcweir
111cdf0e10cSrcweir SetWhichPor( POR_FLD );
112cdf0e10cSrcweir }
113cdf0e10cSrcweir
~SwFldPortion()114cdf0e10cSrcweir SwFldPortion::~SwFldPortion()
115cdf0e10cSrcweir {
116cdf0e10cSrcweir delete pFnt;
117cdf0e10cSrcweir if( pBlink )
118cdf0e10cSrcweir pBlink->Delete( this );
119cdf0e10cSrcweir }
120cdf0e10cSrcweir
121cdf0e10cSrcweir /*************************************************************************
122cdf0e10cSrcweir * virtual SwFldPortion::GetViewWidth()
123cdf0e10cSrcweir *************************************************************************/
124cdf0e10cSrcweir
GetViewWidth(const SwTxtSizeInfo & rInf) const125cdf0e10cSrcweir KSHORT SwFldPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
126cdf0e10cSrcweir {
127cdf0e10cSrcweir // Wir stehen zwar im const, aber nViewWidth sollte erst im letzten
128cdf0e10cSrcweir // Moment errechnet werden:
129cdf0e10cSrcweir SwFldPortion* pThis = (SwFldPortion*)this;
130cdf0e10cSrcweir if( !Width() && rInf.OnWin() && !rInf.GetOpt().IsPagePreview() &&
131cdf0e10cSrcweir !rInf.GetOpt().IsReadonly() && SwViewOption::IsFieldShadings() )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir if( !nViewWidth )
134cdf0e10cSrcweir pThis->nViewWidth = rInf.GetTxtSize( ' ' ).Width();
135cdf0e10cSrcweir }
136cdf0e10cSrcweir else
137cdf0e10cSrcweir pThis->nViewWidth = 0;
138cdf0e10cSrcweir return nViewWidth;
139cdf0e10cSrcweir }
140cdf0e10cSrcweir
141cdf0e10cSrcweir /*************************************************************************
142cdf0e10cSrcweir * virtual SwFldPortion::Format()
143cdf0e10cSrcweir *************************************************************************/
144cdf0e10cSrcweir
145cdf0e10cSrcweir // 8653: in keinem Fall nur SetLen(0);
146cdf0e10cSrcweir
147cdf0e10cSrcweir /*************************************************************************
148cdf0e10cSrcweir * Hilfsklasse SwFldSlot
149cdf0e10cSrcweir **************************************************************************/
150cdf0e10cSrcweir
151cdf0e10cSrcweir class SwFldSlot
152cdf0e10cSrcweir {
153cdf0e10cSrcweir const XubString *pOldTxt;
154cdf0e10cSrcweir XubString aTxt;
155cdf0e10cSrcweir xub_StrLen nIdx;
156cdf0e10cSrcweir xub_StrLen nLen;
157cdf0e10cSrcweir sal_Bool bOn;
158cdf0e10cSrcweir SwTxtFormatInfo *pInf;
159cdf0e10cSrcweir public:
160cdf0e10cSrcweir SwFldSlot( const SwTxtFormatInfo* pNew, const SwFldPortion *pPor );
161cdf0e10cSrcweir ~SwFldSlot();
162cdf0e10cSrcweir };
163cdf0e10cSrcweir
SwFldSlot(const SwTxtFormatInfo * pNew,const SwFldPortion * pPor)164cdf0e10cSrcweir SwFldSlot::SwFldSlot( const SwTxtFormatInfo* pNew, const SwFldPortion *pPor )
165cdf0e10cSrcweir {
166cdf0e10cSrcweir bOn = pPor->GetExpTxt( *pNew, aTxt );
167cdf0e10cSrcweir
168cdf0e10cSrcweir // Der Text wird ausgetauscht...
169cdf0e10cSrcweir if( bOn )
170cdf0e10cSrcweir {
171cdf0e10cSrcweir pInf = (SwTxtFormatInfo*)pNew;
172cdf0e10cSrcweir nIdx = pInf->GetIdx();
173cdf0e10cSrcweir nLen = pInf->GetLen();
174cdf0e10cSrcweir pOldTxt = &(pInf->GetTxt());
175cdf0e10cSrcweir pInf->SetLen( aTxt.Len() );
176cdf0e10cSrcweir if( pPor->IsFollow() )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir pInf->SetFakeLineStart( nIdx > pInf->GetLineStart() );
179cdf0e10cSrcweir pInf->SetIdx( 0 );
180cdf0e10cSrcweir }
181cdf0e10cSrcweir else
182cdf0e10cSrcweir {
183cdf0e10cSrcweir XubString aTmp( aTxt );
184cdf0e10cSrcweir aTxt = *pOldTxt;
185cdf0e10cSrcweir aTxt.Erase( nIdx, 1 );
186cdf0e10cSrcweir aTxt.Insert( aTmp, nIdx );
187cdf0e10cSrcweir }
188cdf0e10cSrcweir pInf->SetTxt( aTxt );
189cdf0e10cSrcweir }
190cdf0e10cSrcweir }
191cdf0e10cSrcweir
~SwFldSlot()192cdf0e10cSrcweir SwFldSlot::~SwFldSlot()
193cdf0e10cSrcweir {
194cdf0e10cSrcweir if( bOn )
195cdf0e10cSrcweir {
196cdf0e10cSrcweir pInf->SetTxt( *pOldTxt );
197cdf0e10cSrcweir pInf->SetIdx( nIdx );
198cdf0e10cSrcweir pInf->SetLen( nLen );
199cdf0e10cSrcweir pInf->SetFakeLineStart( sal_False );
200cdf0e10cSrcweir }
201cdf0e10cSrcweir }
202cdf0e10cSrcweir
CheckScript(const SwTxtSizeInfo & rInf)203cdf0e10cSrcweir void SwFldPortion::CheckScript( const SwTxtSizeInfo &rInf )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir String aTxt;
206cdf0e10cSrcweir if( GetExpTxt( rInf, aTxt ) && aTxt.Len() && pBreakIt->GetBreakIter().is() )
207cdf0e10cSrcweir {
208cdf0e10cSrcweir sal_uInt8 nActual = pFnt ? pFnt->GetActual() : rInf.GetFont()->GetActual();
209cdf0e10cSrcweir sal_uInt16 nScript;
210cdf0e10cSrcweir {
211cdf0e10cSrcweir nScript = pBreakIt->GetBreakIter()->getScriptType( aTxt, 0 );
212cdf0e10cSrcweir xub_StrLen nChg = 0;
213cdf0e10cSrcweir if( i18n::ScriptType::WEAK == nScript )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir nChg =(xub_StrLen)pBreakIt->GetBreakIter()->endOfScript(aTxt,0,nScript);
216cdf0e10cSrcweir if( nChg < aTxt.Len() )
217cdf0e10cSrcweir nScript = pBreakIt->GetBreakIter()->getScriptType( aTxt, nChg );
218cdf0e10cSrcweir }
219cdf0e10cSrcweir
220cdf0e10cSrcweir //
221cdf0e10cSrcweir // nNextScriptChg will be evaluated during SwFldPortion::Format()
222cdf0e10cSrcweir //
223cdf0e10cSrcweir if ( nChg < aTxt.Len() )
224cdf0e10cSrcweir nNextScriptChg = (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( aTxt, nChg, nScript );
225cdf0e10cSrcweir else
226cdf0e10cSrcweir nNextScriptChg = aTxt.Len();
227cdf0e10cSrcweir
228cdf0e10cSrcweir }
229cdf0e10cSrcweir sal_uInt8 nTmp;
230cdf0e10cSrcweir switch ( nScript ) {
231cdf0e10cSrcweir case i18n::ScriptType::LATIN : nTmp = SW_LATIN; break;
232cdf0e10cSrcweir case i18n::ScriptType::ASIAN : nTmp = SW_CJK; break;
233cdf0e10cSrcweir case i18n::ScriptType::COMPLEX : nTmp = SW_CTL; break;
234cdf0e10cSrcweir default: nTmp = nActual;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir
237cdf0e10cSrcweir // #i16354# Change script type for RTL text to CTL.
238cdf0e10cSrcweir const SwScriptInfo& rSI = rInf.GetParaPortion()->GetScriptInfo();
239cdf0e10cSrcweir // --> OD 2009-01-29 #i98418#
240cdf0e10cSrcweir // const sal_uInt8 nFldDir = IsNumberPortion() ?
241cdf0e10cSrcweir const sal_uInt8 nFldDir = ( IsNumberPortion() || IsFtnNumPortion() ) ?
242cdf0e10cSrcweir rSI.GetDefaultDir() :
243cdf0e10cSrcweir rSI.DirType( IsFollow() ? rInf.GetIdx() - 1 : rInf.GetIdx() );
244cdf0e10cSrcweir // <--
245cdf0e10cSrcweir if ( UBIDI_RTL == nFldDir )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir UErrorCode nError = U_ZERO_ERROR;
248cdf0e10cSrcweir UBiDi* pBidi = ubidi_openSized( aTxt.Len(), 0, &nError );
249cdf0e10cSrcweir ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(aTxt.GetBuffer()), aTxt.Len(), nFldDir, NULL, &nError );
250cdf0e10cSrcweir int32_t nEnd;
251cdf0e10cSrcweir UBiDiLevel nCurrDir;
252cdf0e10cSrcweir ubidi_getLogicalRun( pBidi, 0, &nEnd, &nCurrDir );
253cdf0e10cSrcweir ubidi_close( pBidi );
254cdf0e10cSrcweir const xub_StrLen nNextDirChg = (xub_StrLen)nEnd;
255cdf0e10cSrcweir nNextScriptChg = Min( nNextScriptChg, nNextDirChg );
256cdf0e10cSrcweir
257cdf0e10cSrcweir // #i89825# change the script type also to CTL
258cdf0e10cSrcweir // if there is no strong LTR char in the LTR run (numbers)
259cdf0e10cSrcweir if ( nCurrDir != UBIDI_RTL )
260cdf0e10cSrcweir {
261cdf0e10cSrcweir nCurrDir = UBIDI_RTL;
262cdf0e10cSrcweir for ( xub_StrLen nCharIdx = 0; nCharIdx < nEnd; ++nCharIdx )
263cdf0e10cSrcweir {
264cdf0e10cSrcweir UCharDirection nCharDir = u_charDirection ( aTxt.GetChar ( nCharIdx ));
265cdf0e10cSrcweir if ( nCharDir == U_LEFT_TO_RIGHT ||
266cdf0e10cSrcweir nCharDir == U_LEFT_TO_RIGHT_EMBEDDING ||
267cdf0e10cSrcweir nCharDir == U_LEFT_TO_RIGHT_OVERRIDE )
268cdf0e10cSrcweir {
269cdf0e10cSrcweir nCurrDir = UBIDI_LTR;
270cdf0e10cSrcweir break;
271cdf0e10cSrcweir }
272cdf0e10cSrcweir }
273cdf0e10cSrcweir }
274cdf0e10cSrcweir
275cdf0e10cSrcweir if ( nCurrDir == UBIDI_RTL )
276cdf0e10cSrcweir nTmp = SW_CTL;
277cdf0e10cSrcweir }
278cdf0e10cSrcweir
279cdf0e10cSrcweir // --> OD 2009-01-29 #i98418#
280cdf0e10cSrcweir // keep determined script type for footnote portions as preferred script type.
281cdf0e10cSrcweir // For footnote portions a font can not be created directly - see footnote
282cdf0e10cSrcweir // portion format method.
283cdf0e10cSrcweir // if( !IsFtnPortion() && nTmp != nActual )
284cdf0e10cSrcweir if ( IsFtnPortion() )
285cdf0e10cSrcweir {
286cdf0e10cSrcweir dynamic_cast<SwFtnPortion*>(this)->SetPreferredScriptType( nTmp );
287cdf0e10cSrcweir }
288cdf0e10cSrcweir else if ( nTmp != nActual )
289cdf0e10cSrcweir {
290cdf0e10cSrcweir if( !pFnt )
291cdf0e10cSrcweir pFnt = new SwFont( *rInf.GetFont() );
292cdf0e10cSrcweir pFnt->SetActual( nTmp );
293cdf0e10cSrcweir }
294cdf0e10cSrcweir // <--
295cdf0e10cSrcweir }
296cdf0e10cSrcweir }
297cdf0e10cSrcweir
Format(SwTxtFormatInfo & rInf)298cdf0e10cSrcweir sal_Bool SwFldPortion::Format( SwTxtFormatInfo &rInf )
299cdf0e10cSrcweir {
300cdf0e10cSrcweir // Scope wegen aDiffTxt::DTOR!
301cdf0e10cSrcweir xub_StrLen nRest;
302cdf0e10cSrcweir sal_Bool bFull;
303cdf0e10cSrcweir sal_Bool bEOL = sal_False;
304cdf0e10cSrcweir long nTxtRest = rInf.GetTxt().Len() - rInf.GetIdx();
305cdf0e10cSrcweir {
306cdf0e10cSrcweir SwFldSlot aDiffTxt( &rInf, this );
307cdf0e10cSrcweir SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
308cdf0e10cSrcweir aLayoutModeModifier.SetAuto();
309cdf0e10cSrcweir
310cdf0e10cSrcweir // Field portion has to be split in several parts if
311cdf0e10cSrcweir // 1. There are script/direction changes inside the field
312cdf0e10cSrcweir // 2. There are portion breaks (tab, break) inside the field:
313cdf0e10cSrcweir const xub_StrLen nOldFullLen = rInf.GetLen();
314cdf0e10cSrcweir xub_StrLen nFullLen = rInf.ScanPortionEnd( rInf.GetIdx(), rInf.GetIdx() + nOldFullLen ) - rInf.GetIdx();
315cdf0e10cSrcweir if ( nNextScriptChg < nFullLen )
316cdf0e10cSrcweir {
317cdf0e10cSrcweir nFullLen = nNextScriptChg;
318cdf0e10cSrcweir rInf.SetHookChar( 0 );
319cdf0e10cSrcweir }
320cdf0e10cSrcweir rInf.SetLen( nFullLen );
321cdf0e10cSrcweir
322cdf0e10cSrcweir if ( STRING_LEN != rInf.GetUnderScorePos() &&
323cdf0e10cSrcweir rInf.GetUnderScorePos() > rInf.GetIdx() )
324cdf0e10cSrcweir rInf.SetUnderScorePos( rInf.GetIdx() );
325cdf0e10cSrcweir
326cdf0e10cSrcweir if( pFnt )
327cdf0e10cSrcweir pFnt->GoMagic( rInf.GetVsh(), pFnt->GetActual() );
328cdf0e10cSrcweir
329cdf0e10cSrcweir SwFontSave aSave( rInf, pFnt );
330cdf0e10cSrcweir
331cdf0e10cSrcweir // 8674: Laenge muss 0 sein, bei bFull nach Format ist die Laenge
332cdf0e10cSrcweir // gesetzt und wird in nRest uebertragen. Ansonsten bleibt die
333cdf0e10cSrcweir // Laenge erhalten und wuerde auch in nRest einfliessen!
334cdf0e10cSrcweir SetLen(0);
335cdf0e10cSrcweir const MSHORT nFollow = IsFollow() ? 0 : 1;
336cdf0e10cSrcweir
337cdf0e10cSrcweir // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der
338cdf0e10cSrcweir // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs)
339cdf0e10cSrcweir // sal_False returnen wegen SetFull ...
340cdf0e10cSrcweir if( !nFullLen )
341cdf0e10cSrcweir {
342cdf0e10cSrcweir // nicht Init(), weil wir Hoehe und Ascent brauchen
343cdf0e10cSrcweir Width(0);
344cdf0e10cSrcweir bFull = rInf.Width() <= rInf.GetPos().X();
345cdf0e10cSrcweir }
346cdf0e10cSrcweir else
347cdf0e10cSrcweir {
348cdf0e10cSrcweir xub_StrLen nOldLineStart = rInf.GetLineStart();
349cdf0e10cSrcweir if( IsFollow() )
350cdf0e10cSrcweir rInf.SetLineStart( 0 );
351cdf0e10cSrcweir rInf.SetNotEOL( nFullLen == nOldFullLen && nTxtRest > nFollow );
352cdf0e10cSrcweir
353cdf0e10cSrcweir // the height depending on the fields font is set,
354cdf0e10cSrcweir // this is required for SwTxtGuess::Guess
355cdf0e10cSrcweir Height( rInf.GetTxtHeight() );
356cdf0e10cSrcweir // If a kerning portion is inserted after our field portion,
357cdf0e10cSrcweir // the ascent and height must be known
358cdf0e10cSrcweir SetAscent( rInf.GetAscent() );
359cdf0e10cSrcweir bFull = SwTxtPortion::Format( rInf );
360cdf0e10cSrcweir rInf.SetNotEOL( sal_False );
361cdf0e10cSrcweir rInf.SetLineStart( nOldLineStart );
362cdf0e10cSrcweir }
363cdf0e10cSrcweir xub_StrLen nTmpLen = GetLen();
364cdf0e10cSrcweir bEOL = !nTmpLen && nFollow && bFull;
365cdf0e10cSrcweir nRest = nOldFullLen - nTmpLen;
366cdf0e10cSrcweir
367cdf0e10cSrcweir // Das Zeichen wird in der ersten Portion gehalten.
368cdf0e10cSrcweir // Unbedingt nach Format!
369cdf0e10cSrcweir SetLen( (m_bNoLength) ? 0 : nFollow );
370cdf0e10cSrcweir
371cdf0e10cSrcweir if( nRest )
372cdf0e10cSrcweir {
373cdf0e10cSrcweir // aExpand ist noch nicht gekuerzt worden, der neue Ofst
374cdf0e10cSrcweir // ergibt sich durch nRest.
375cdf0e10cSrcweir xub_StrLen nNextOfst = aExpand.Len() - nRest;
376cdf0e10cSrcweir
377cdf0e10cSrcweir if ( IsQuoVadisPortion() )
378cdf0e10cSrcweir nNextOfst = nNextOfst + ((SwQuoVadisPortion*)this)->GetContTxt().Len();
379cdf0e10cSrcweir
380cdf0e10cSrcweir XubString aNew( aExpand, nNextOfst, STRING_LEN );
381cdf0e10cSrcweir aExpand.Erase( nNextOfst, STRING_LEN );
382cdf0e10cSrcweir
383cdf0e10cSrcweir // These characters should not be contained in the follow
384cdf0e10cSrcweir // field portion. They are handled via the HookChar mechanism.
385cdf0e10cSrcweir switch( aNew.GetChar( 0 ))
386cdf0e10cSrcweir {
387cdf0e10cSrcweir case CH_BREAK : bFull = sal_True;
388cdf0e10cSrcweir // kein break;
389cdf0e10cSrcweir case ' ' :
390cdf0e10cSrcweir case CH_TAB :
391cdf0e10cSrcweir case CHAR_HARDHYPHEN: // non-breaking hyphen
392cdf0e10cSrcweir case CHAR_SOFTHYPHEN:
393cdf0e10cSrcweir case CHAR_HARDBLANK:
394cdf0e10cSrcweir case CHAR_ZWSP :
395cdf0e10cSrcweir case CHAR_ZWNBSP :
396cdf0e10cSrcweir case CH_TXTATR_BREAKWORD:
397cdf0e10cSrcweir case CH_TXTATR_INWORD:
398cdf0e10cSrcweir {
399cdf0e10cSrcweir aNew.Erase( 0, 1 );
400cdf0e10cSrcweir ++nNextOfst;
401cdf0e10cSrcweir break;
402cdf0e10cSrcweir }
403cdf0e10cSrcweir default: ;
404cdf0e10cSrcweir }
405cdf0e10cSrcweir
406cdf0e10cSrcweir // Even if there is no more text left for a follow field,
407cdf0e10cSrcweir // we have to build a follow field portion (without font),
408cdf0e10cSrcweir // otherwise the HookChar mechanism would not work.
409cdf0e10cSrcweir SwFldPortion *pFld = Clone( aNew );
410cdf0e10cSrcweir if( aNew.Len() && !pFld->GetFont() )
411cdf0e10cSrcweir {
412cdf0e10cSrcweir SwFont *pNewFnt = new SwFont( *rInf.GetFont() );
413cdf0e10cSrcweir pFld->SetFont( pNewFnt );
414cdf0e10cSrcweir }
415cdf0e10cSrcweir pFld->SetFollow( sal_True );
416cdf0e10cSrcweir SetHasFollow( sal_True );
417cdf0e10cSrcweir // In nNextOffset steht bei einem neuangelegten Feld zunaechst
418cdf0e10cSrcweir // der Offset, an dem es selbst im Originalstring beginnt.
419cdf0e10cSrcweir // Wenn beim Formatieren ein FollowFeld angelegt wird, wird
420cdf0e10cSrcweir // der Offset dieses FollowFelds in nNextOffset festgehalten.
421cdf0e10cSrcweir nNextOffset = nNextOffset + nNextOfst;
422cdf0e10cSrcweir pFld->SetNextOffset( nNextOffset );
423cdf0e10cSrcweir rInf.SetRest( pFld );
424cdf0e10cSrcweir }
425cdf0e10cSrcweir }
426cdf0e10cSrcweir
427cdf0e10cSrcweir if( bEOL && rInf.GetLast() && !rInf.GetUnderFlow() )
428cdf0e10cSrcweir rInf.GetLast()->FormatEOL( rInf );
429cdf0e10cSrcweir return bFull;
430cdf0e10cSrcweir }
431cdf0e10cSrcweir
432cdf0e10cSrcweir /*************************************************************************
433cdf0e10cSrcweir * virtual SwFldPortion::Paint()
434cdf0e10cSrcweir *************************************************************************/
435cdf0e10cSrcweir
Paint(const SwTxtPaintInfo & rInf) const436cdf0e10cSrcweir void SwFldPortion::Paint( const SwTxtPaintInfo &rInf ) const
437cdf0e10cSrcweir {
438cdf0e10cSrcweir SwFontSave aSave( rInf, pFnt );
439cdf0e10cSrcweir
440*86e1cf34SPedro Giffuni ASSERT( GetLen() <= 1, "SwFldPortion::Paint: rest-portion pollution?" );
441cdf0e10cSrcweir if( Width() && ( !bPlaceHolder || rInf.GetOpt().IsShowPlaceHolderFields() ) )
442cdf0e10cSrcweir {
443cdf0e10cSrcweir // Dies ist eine freizuegige Auslegung der Hintergrundbelegung ...
444cdf0e10cSrcweir rInf.DrawViewOpt( *this, POR_FLD );
445cdf0e10cSrcweir SwExpandPortion::Paint( rInf );
446cdf0e10cSrcweir }
447cdf0e10cSrcweir }
448cdf0e10cSrcweir
449cdf0e10cSrcweir /*************************************************************************
450cdf0e10cSrcweir * virtual SwFldPortion::GetExpTxt()
451cdf0e10cSrcweir *************************************************************************/
452cdf0e10cSrcweir
GetExpTxt(const SwTxtSizeInfo & rInf,XubString & rTxt) const453cdf0e10cSrcweir sal_Bool SwFldPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
454cdf0e10cSrcweir {
455cdf0e10cSrcweir rTxt = aExpand;
456cdf0e10cSrcweir if( !rTxt.Len() && rInf.OnWin() &&
457cdf0e10cSrcweir !rInf.GetOpt().IsPagePreview() && !rInf.GetOpt().IsReadonly() &&
458cdf0e10cSrcweir SwViewOption::IsFieldShadings() &&
459cdf0e10cSrcweir !HasFollow() )
460cdf0e10cSrcweir rTxt = ' ';
461cdf0e10cSrcweir return sal_True;
462cdf0e10cSrcweir }
463cdf0e10cSrcweir
464cdf0e10cSrcweir /*************************************************************************
465cdf0e10cSrcweir * virtual SwFldPortion::HandlePortion()
466cdf0e10cSrcweir *************************************************************************/
467cdf0e10cSrcweir
HandlePortion(SwPortionHandler & rPH) const468cdf0e10cSrcweir void SwFldPortion::HandlePortion( SwPortionHandler& rPH ) const
469cdf0e10cSrcweir {
470cdf0e10cSrcweir rPH.Special( GetLen(), aExpand, GetWhichPor() );
471ca62e2c2SSteve Yin if( GetWhichPor() == POR_FLD )
472ca62e2c2SSteve Yin {
473ca62e2c2SSteve Yin rPH.SetAttrFieldType(m_nAttrFldType);
474ca62e2c2SSteve Yin }
475cdf0e10cSrcweir }
476cdf0e10cSrcweir
477cdf0e10cSrcweir /*************************************************************************
478cdf0e10cSrcweir * virtual SwFldPortion::GetTxtSize()
479cdf0e10cSrcweir *************************************************************************/
480cdf0e10cSrcweir
GetTxtSize(const SwTxtSizeInfo & rInf) const481cdf0e10cSrcweir SwPosSize SwFldPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
482cdf0e10cSrcweir {
483cdf0e10cSrcweir SwFontSave aSave( rInf, pFnt );
484cdf0e10cSrcweir SwPosSize aSize( SwExpandPortion::GetTxtSize( rInf ) );
485cdf0e10cSrcweir return aSize;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir
488cdf0e10cSrcweir /*************************************************************************
489cdf0e10cSrcweir * class SwHiddenPortion
490cdf0e10cSrcweir *************************************************************************/
491cdf0e10cSrcweir
Clone(const XubString & rExpand) const492cdf0e10cSrcweir SwFldPortion *SwHiddenPortion::Clone(const XubString &rExpand ) const
493cdf0e10cSrcweir {
494cdf0e10cSrcweir SwFont *pNewFnt;
495cdf0e10cSrcweir if( 0 != ( pNewFnt = pFnt ) )
496cdf0e10cSrcweir pNewFnt = new SwFont( *pFnt );
497cdf0e10cSrcweir return new SwHiddenPortion( rExpand, pNewFnt );
498cdf0e10cSrcweir }
499cdf0e10cSrcweir
500cdf0e10cSrcweir /*************************************************************************
501cdf0e10cSrcweir * virtual SwHiddenPortion::Paint()
502cdf0e10cSrcweir *************************************************************************/
503cdf0e10cSrcweir
Paint(const SwTxtPaintInfo & rInf) const504cdf0e10cSrcweir void SwHiddenPortion::Paint( const SwTxtPaintInfo &rInf ) const
505cdf0e10cSrcweir {
506cdf0e10cSrcweir if( Width() )
507cdf0e10cSrcweir {
508cdf0e10cSrcweir SwFontSave aSave( rInf, pFnt );
509cdf0e10cSrcweir rInf.DrawViewOpt( *this, POR_HIDDEN );
510cdf0e10cSrcweir SwExpandPortion::Paint( rInf );
511cdf0e10cSrcweir }
512cdf0e10cSrcweir }
513cdf0e10cSrcweir
514cdf0e10cSrcweir /*************************************************************************
515cdf0e10cSrcweir * virtual SwHiddenPortion::GetExpTxt()
516cdf0e10cSrcweir *************************************************************************/
517cdf0e10cSrcweir
GetExpTxt(const SwTxtSizeInfo & rInf,XubString & rTxt) const518cdf0e10cSrcweir sal_Bool SwHiddenPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
519cdf0e10cSrcweir {
520cdf0e10cSrcweir // Nicht auf IsHidden() abfragen !
521cdf0e10cSrcweir return SwFldPortion::GetExpTxt( rInf, rTxt );
522cdf0e10cSrcweir }
523cdf0e10cSrcweir
524cdf0e10cSrcweir /*************************************************************************
525cdf0e10cSrcweir * class SwNumberPortion
526cdf0e10cSrcweir *************************************************************************/
527cdf0e10cSrcweir
528cdf0e10cSrcweir // --> OD 2008-01-23 #newlistlevelattrs#
SwNumberPortion(const XubString & rExpand,SwFont * pFont,const sal_Bool bLft,const sal_Bool bCntr,const KSHORT nMinDst,const bool bLabelAlignmentPosAndSpaceModeActive)529cdf0e10cSrcweir SwNumberPortion::SwNumberPortion( const XubString &rExpand,
530cdf0e10cSrcweir SwFont *pFont,
531cdf0e10cSrcweir const sal_Bool bLft,
532cdf0e10cSrcweir const sal_Bool bCntr,
533cdf0e10cSrcweir const KSHORT nMinDst,
534cdf0e10cSrcweir const bool bLabelAlignmentPosAndSpaceModeActive )
535cdf0e10cSrcweir : SwFldPortion( rExpand, pFont ),
536cdf0e10cSrcweir nFixWidth(0),
537cdf0e10cSrcweir nMinDist( nMinDst ),
538cdf0e10cSrcweir // --> OD 2008-01-23 #newlistlevelattrs#
539cdf0e10cSrcweir mbLabelAlignmentPosAndSpaceModeActive( bLabelAlignmentPosAndSpaceModeActive )
540cdf0e10cSrcweir // <--
541cdf0e10cSrcweir {
542cdf0e10cSrcweir SetWhichPor( POR_NUMBER );
543cdf0e10cSrcweir SetLeft( bLft );
544cdf0e10cSrcweir SetHide( sal_False );
545cdf0e10cSrcweir SetCenter( bCntr );
546cdf0e10cSrcweir }
547cdf0e10cSrcweir
GetCrsrOfst(const MSHORT) const548cdf0e10cSrcweir xub_StrLen SwNumberPortion::GetCrsrOfst( const MSHORT ) const
549cdf0e10cSrcweir {
550cdf0e10cSrcweir return 0;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir
Clone(const XubString & rExpand) const553cdf0e10cSrcweir SwFldPortion *SwNumberPortion::Clone( const XubString &rExpand ) const
554cdf0e10cSrcweir {
555cdf0e10cSrcweir SwFont *pNewFnt;
556cdf0e10cSrcweir if( 0 != ( pNewFnt = pFnt ) )
557cdf0e10cSrcweir pNewFnt = new SwFont( *pFnt );
558cdf0e10cSrcweir // --> OD 2008-01-23 #newlistlevelattrs#
559cdf0e10cSrcweir return new SwNumberPortion( rExpand, pNewFnt, IsLeft(), IsCenter(),
560cdf0e10cSrcweir nMinDist, mbLabelAlignmentPosAndSpaceModeActive );
561cdf0e10cSrcweir // <--
562cdf0e10cSrcweir }
563cdf0e10cSrcweir
564cdf0e10cSrcweir /*************************************************************************
565cdf0e10cSrcweir * virtual SwNumberPortion::Format()
566cdf0e10cSrcweir *************************************************************************/
567cdf0e10cSrcweir
568cdf0e10cSrcweir // 5010: Wir sind in der Lage, mehrzeilige NumFelder anzulegen!
569cdf0e10cSrcweir // 3689: Fies ist, wenn man in der Dialogbox soviel Davor-Text
570cdf0e10cSrcweir // eingibt, bis die Zeile ueberlaeuft.
571cdf0e10cSrcweir // Man muss die Fly-Ausweichmanoever beachten!
572cdf0e10cSrcweir
Format(SwTxtFormatInfo & rInf)573cdf0e10cSrcweir sal_Bool SwNumberPortion::Format( SwTxtFormatInfo &rInf )
574cdf0e10cSrcweir {
575cdf0e10cSrcweir SetHide( sal_False );
576cdf0e10cSrcweir const sal_Bool bFull = SwFldPortion::Format( rInf );
577cdf0e10cSrcweir SetLen( 0 );
578cdf0e10cSrcweir // a numbering portion can be contained in a rotated portion!!!
579cdf0e10cSrcweir nFixWidth = rInf.IsMulti() ? Height() : Width();
580cdf0e10cSrcweir rInf.SetNumDone( !rInf.GetRest() );
581cdf0e10cSrcweir if( rInf.IsNumDone() )
582cdf0e10cSrcweir {
583cdf0e10cSrcweir // SetAscent( rInf.GetAscent() );
584cdf0e10cSrcweir ASSERT( Height() && nAscent, "NumberPortions without Height | Ascent" );
585cdf0e10cSrcweir
586cdf0e10cSrcweir long nDiff( 0 );
587cdf0e10cSrcweir // --> OD 2008-01-23 #newlistlevelattrs#
588cdf0e10cSrcweir if ( !mbLabelAlignmentPosAndSpaceModeActive )
589cdf0e10cSrcweir {
590cdf0e10cSrcweir if ( !rInf.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) &&
591cdf0e10cSrcweir // --> FME 2004-08-13 #i32902#
592cdf0e10cSrcweir !IsFtnNumPortion() )
593cdf0e10cSrcweir // <--
594cdf0e10cSrcweir {
595cdf0e10cSrcweir nDiff = rInf.Left()
596cdf0e10cSrcweir + rInf.GetTxtFrm()->GetTxtNode()->
597cdf0e10cSrcweir GetSwAttrSet().GetLRSpace().GetTxtFirstLineOfst()
598cdf0e10cSrcweir - rInf.First()
599cdf0e10cSrcweir + rInf.ForcedLeftMargin();
600cdf0e10cSrcweir }
601cdf0e10cSrcweir else
602cdf0e10cSrcweir {
603cdf0e10cSrcweir nDiff = rInf.Left() - rInf.First() + rInf.ForcedLeftMargin();
604cdf0e10cSrcweir }
605cdf0e10cSrcweir }
606cdf0e10cSrcweir // <--
607cdf0e10cSrcweir // Ein Vorschlag von Juergen und Volkmar:
608cdf0e10cSrcweir // Der Textteil hinter der Numerierung sollte immer
609cdf0e10cSrcweir // mindestens beim linken Rand beginnen.
610cdf0e10cSrcweir if( nDiff < 0 )
611cdf0e10cSrcweir nDiff = 0;
612cdf0e10cSrcweir else if ( nDiff > rInf.X() )
613cdf0e10cSrcweir nDiff -= rInf.X();
614cdf0e10cSrcweir else
615cdf0e10cSrcweir nDiff = 0;
616cdf0e10cSrcweir
617cdf0e10cSrcweir if( nDiff < nFixWidth + nMinDist )
618cdf0e10cSrcweir nDiff = nFixWidth + nMinDist;
619cdf0e10cSrcweir // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde
620cdf0e10cSrcweir // fieser Sonderfall: FlyFrm liegt in dem Bereich,
621cdf0e10cSrcweir // den wir uns gerade unter den Nagel reissen wollen.
622cdf0e10cSrcweir // Die NumberPortion wird als verborgen markiert.
623cdf0e10cSrcweir const sal_Bool bFly = rInf.GetFly() ||
624cdf0e10cSrcweir ( rInf.GetLast() && rInf.GetLast()->IsFlyPortion() );
625cdf0e10cSrcweir if( nDiff > rInf.Width() )
626cdf0e10cSrcweir {
627cdf0e10cSrcweir nDiff = rInf.Width();
628cdf0e10cSrcweir if ( bFly )
629cdf0e10cSrcweir SetHide( sal_True );
630cdf0e10cSrcweir }
631cdf0e10cSrcweir
632cdf0e10cSrcweir // A numbering portion can be inside a SwRotatedPortion. Then the
633cdf0e10cSrcweir // Height has to be changed
634cdf0e10cSrcweir if ( rInf.IsMulti() )
635cdf0e10cSrcweir {
636cdf0e10cSrcweir if ( Height() < nDiff )
637cdf0e10cSrcweir Height( KSHORT( nDiff ) );
638cdf0e10cSrcweir }
639cdf0e10cSrcweir else if( Width() < nDiff )
640cdf0e10cSrcweir Width( KSHORT(nDiff) );
641cdf0e10cSrcweir }
642cdf0e10cSrcweir return bFull;
643cdf0e10cSrcweir }
644cdf0e10cSrcweir
FormatEOL(SwTxtFormatInfo &)645cdf0e10cSrcweir void SwNumberPortion::FormatEOL( SwTxtFormatInfo& )
646cdf0e10cSrcweir {
647cdf0e10cSrcweir /* Ein FormatEOL deutet daraufhin, dass der folgende Text
648cdf0e10cSrcweir * nicht mit auf die Zeile passte. Damit die Numerierung mitwandert,
649cdf0e10cSrcweir * wird diese NumberPortion verborgen.
650cdf0e10cSrcweir */
651cdf0e10cSrcweir
652cdf0e10cSrcweir // This caused trouble with flys anchored as characters.
653cdf0e10cSrcweir // If one of these is numbered but does not fit to the line,
654cdf0e10cSrcweir // it calls this function, causing a loop because both the number
655cdf0e10cSrcweir // portion and the fly portion go to the next line
656cdf0e10cSrcweir // SetHide( sal_True );
657cdf0e10cSrcweir }
658cdf0e10cSrcweir
659cdf0e10cSrcweir /*************************************************************************
660cdf0e10cSrcweir * virtual SwNumberPortion::Paint()
661cdf0e10cSrcweir *************************************************************************/
662cdf0e10cSrcweir
Paint(const SwTxtPaintInfo & rInf) const663cdf0e10cSrcweir void SwNumberPortion::Paint( const SwTxtPaintInfo &rInf ) const
664cdf0e10cSrcweir {
665cdf0e10cSrcweir /* Eine verborgene NumberPortion wird nicht angezeigt, es sei denn, es gibt
666cdf0e10cSrcweir * Textportions in dieser Zeile oder es gibt ueberhaupt nur eine einzige Zeile.
667cdf0e10cSrcweir */
668cdf0e10cSrcweir
669cdf0e10cSrcweir if ( IsHide() && rInf.GetParaPortion() && rInf.GetParaPortion()->GetNext() )
670cdf0e10cSrcweir {
671cdf0e10cSrcweir SwLinePortion *pTmp = GetPortion();
672cdf0e10cSrcweir while ( pTmp && !pTmp->InTxtGrp() )
673cdf0e10cSrcweir pTmp = pTmp->GetPortion();
674cdf0e10cSrcweir if ( !pTmp )
675cdf0e10cSrcweir return;
676cdf0e10cSrcweir }
677cdf0e10cSrcweir
678cdf0e10cSrcweir // calculate the width of the number portion, including follows
679cdf0e10cSrcweir const KSHORT nOldWidth = Width();
680cdf0e10cSrcweir sal_uInt16 nSumWidth = 0;
681cdf0e10cSrcweir sal_uInt16 nOffset = 0;
682cdf0e10cSrcweir
683cdf0e10cSrcweir const SwLinePortion* pTmp = this;
684cdf0e10cSrcweir while ( pTmp && pTmp->InNumberGrp() )
685cdf0e10cSrcweir {
686cdf0e10cSrcweir nSumWidth = nSumWidth + pTmp->Width();
687cdf0e10cSrcweir if ( ((SwNumberPortion*)pTmp)->HasFollow() )
688cdf0e10cSrcweir pTmp = pTmp->GetPortion();
689cdf0e10cSrcweir else
690cdf0e10cSrcweir {
691cdf0e10cSrcweir nOffset = pTmp->Width() - ((SwNumberPortion*)pTmp)->nFixWidth;
692cdf0e10cSrcweir break;
693cdf0e10cSrcweir }
694cdf0e10cSrcweir }
695cdf0e10cSrcweir
696cdf0e10cSrcweir // The master portion takes care for painting the background of the
697cdf0e10cSrcweir // follow field portions
698cdf0e10cSrcweir if ( ! IsFollow() )
699cdf0e10cSrcweir {
700cdf0e10cSrcweir SwLinePortion *pThis = (SwLinePortion*)this;
701cdf0e10cSrcweir pThis->Width( nSumWidth );
702cdf0e10cSrcweir rInf.DrawViewOpt( *this, POR_NUMBER );
703cdf0e10cSrcweir pThis->Width( nOldWidth );
704cdf0e10cSrcweir }
705cdf0e10cSrcweir
706cdf0e10cSrcweir if( aExpand.Len() )
707cdf0e10cSrcweir {
708cdf0e10cSrcweir const SwFont *pTmpFnt = rInf.GetFont();
709cdf0e10cSrcweir sal_Bool bPaintSpace = ( UNDERLINE_NONE != pTmpFnt->GetUnderline() ||
710cdf0e10cSrcweir UNDERLINE_NONE != pTmpFnt->GetOverline() ||
711cdf0e10cSrcweir STRIKEOUT_NONE != pTmpFnt->GetStrikeout() ) &&
712cdf0e10cSrcweir !pTmpFnt->IsWordLineMode();
713cdf0e10cSrcweir if( bPaintSpace && pFnt )
714cdf0e10cSrcweir bPaintSpace = ( UNDERLINE_NONE != pFnt->GetUnderline() ||
715cdf0e10cSrcweir UNDERLINE_NONE != pFnt->GetOverline() ||
716cdf0e10cSrcweir STRIKEOUT_NONE != pFnt->GetStrikeout() ) &&
717cdf0e10cSrcweir !pFnt->IsWordLineMode();
718cdf0e10cSrcweir
719cdf0e10cSrcweir SwFontSave aSave( rInf, pFnt );
720cdf0e10cSrcweir
721cdf0e10cSrcweir if( nFixWidth == Width() && ! HasFollow() )
722cdf0e10cSrcweir SwExpandPortion::Paint( rInf );
723cdf0e10cSrcweir else
724cdf0e10cSrcweir {
725cdf0e10cSrcweir // logisches const: Width wird wieder zurueckgesetzt
726cdf0e10cSrcweir SwLinePortion *pThis = (SwLinePortion*)this;
727cdf0e10cSrcweir bPaintSpace = bPaintSpace && nFixWidth < nOldWidth;
728cdf0e10cSrcweir KSHORT nSpaceOffs = nFixWidth;
729cdf0e10cSrcweir pThis->Width( nFixWidth );
730cdf0e10cSrcweir
731cdf0e10cSrcweir if( ( IsLeft() && ! rInf.GetTxtFrm()->IsRightToLeft() ) ||
732cdf0e10cSrcweir ( ! IsLeft() && ! IsCenter() && rInf.GetTxtFrm()->IsRightToLeft() ) )
733cdf0e10cSrcweir SwExpandPortion::Paint( rInf );
734cdf0e10cSrcweir else
735cdf0e10cSrcweir {
736cdf0e10cSrcweir SwTxtPaintInfo aInf( rInf );
737cdf0e10cSrcweir if( nOffset < nMinDist )
738cdf0e10cSrcweir nOffset = 0;
739cdf0e10cSrcweir else
740cdf0e10cSrcweir {
741cdf0e10cSrcweir if( IsCenter() )
742cdf0e10cSrcweir {
743cdf0e10cSrcweir /* #110778# a / 2 * 2 == a is not a tautology */
744cdf0e10cSrcweir KSHORT nTmpOffset = nOffset;
745cdf0e10cSrcweir nOffset /= 2;
746cdf0e10cSrcweir if( nOffset < nMinDist )
747cdf0e10cSrcweir nOffset = nTmpOffset - nMinDist;
748cdf0e10cSrcweir }
749cdf0e10cSrcweir else
750cdf0e10cSrcweir nOffset = nOffset - nMinDist;
751cdf0e10cSrcweir }
752cdf0e10cSrcweir aInf.X( aInf.X() + nOffset );
753cdf0e10cSrcweir SwExpandPortion::Paint( aInf );
754cdf0e10cSrcweir if( bPaintSpace )
755cdf0e10cSrcweir nSpaceOffs = nSpaceOffs + nOffset;
756cdf0e10cSrcweir }
757cdf0e10cSrcweir if( bPaintSpace && nOldWidth > nSpaceOffs )
758cdf0e10cSrcweir {
759cdf0e10cSrcweir SwTxtPaintInfo aInf( rInf );
760cdf0e10cSrcweir static sal_Char __READONLY_DATA sDoubleSpace[] = " ";
761cdf0e10cSrcweir aInf.X( aInf.X() + nSpaceOffs );
762cdf0e10cSrcweir
763cdf0e10cSrcweir // --> FME 2005-08-12 #i53199# Adjust position of underline:
764cdf0e10cSrcweir if ( rInf.GetUnderFnt() )
765cdf0e10cSrcweir {
766cdf0e10cSrcweir const Point aNewPos( aInf.GetPos().X(), rInf.GetUnderFnt()->GetPos().Y() );
767cdf0e10cSrcweir rInf.GetUnderFnt()->SetPos( aNewPos );
768cdf0e10cSrcweir }
769cdf0e10cSrcweir // <--
770cdf0e10cSrcweir
771cdf0e10cSrcweir pThis->Width( nOldWidth - nSpaceOffs + 12 );
772cdf0e10cSrcweir {
773cdf0e10cSrcweir SwTxtSlot aDiffTxt( &aInf, this, true, false, sDoubleSpace );
774cdf0e10cSrcweir aInf.DrawText( *this, aInf.GetLen(), sal_True );
775cdf0e10cSrcweir }
776cdf0e10cSrcweir }
777cdf0e10cSrcweir pThis->Width( nOldWidth );
778cdf0e10cSrcweir }
779cdf0e10cSrcweir }
780cdf0e10cSrcweir }
781cdf0e10cSrcweir
782cdf0e10cSrcweir
783cdf0e10cSrcweir /*************************************************************************
784cdf0e10cSrcweir * class SwBulletPortion
785cdf0e10cSrcweir *************************************************************************/
786cdf0e10cSrcweir
787cdf0e10cSrcweir // --> OD 2008-01-23 #newlistlevelattrs#
SwBulletPortion(const xub_Unicode cBullet,const XubString & rBulletFollowedBy,SwFont * pFont,const sal_Bool bLft,const sal_Bool bCntr,const KSHORT nMinDst,const bool bLabelAlignmentPosAndSpaceModeActive)788cdf0e10cSrcweir SwBulletPortion::SwBulletPortion( const xub_Unicode cBullet,
789cdf0e10cSrcweir const XubString& rBulletFollowedBy,
790cdf0e10cSrcweir SwFont *pFont,
791cdf0e10cSrcweir const sal_Bool bLft,
792cdf0e10cSrcweir const sal_Bool bCntr,
793cdf0e10cSrcweir const KSHORT nMinDst,
794cdf0e10cSrcweir const bool bLabelAlignmentPosAndSpaceModeActive )
795cdf0e10cSrcweir : SwNumberPortion( XubString( rBulletFollowedBy ).Insert( cBullet, 0 ) ,
796cdf0e10cSrcweir pFont, bLft, bCntr, nMinDst,
797cdf0e10cSrcweir bLabelAlignmentPosAndSpaceModeActive )
798cdf0e10cSrcweir // <--
799cdf0e10cSrcweir {
800cdf0e10cSrcweir SetWhichPor( POR_BULLET );
801cdf0e10cSrcweir }
802cdf0e10cSrcweir
803cdf0e10cSrcweir /*************************************************************************
804cdf0e10cSrcweir * class SwGrfNumPortion
805cdf0e10cSrcweir *************************************************************************/
806cdf0e10cSrcweir
807cdf0e10cSrcweir #define GRFNUM_SECURE 10
808cdf0e10cSrcweir
809cdf0e10cSrcweir // --> OD 2008-01-23 #newlistlevelattrs#
SwGrfNumPortion(SwFrm *,const XubString & rGraphicFollowedBy,const SvxBrushItem * pGrfBrush,const SwFmtVertOrient * pGrfOrient,const Size & rGrfSize,const sal_Bool bLft,const sal_Bool bCntr,const KSHORT nMinDst,const bool bLabelAlignmentPosAndSpaceModeActive)810cdf0e10cSrcweir SwGrfNumPortion::SwGrfNumPortion(
811cdf0e10cSrcweir SwFrm*,
812cdf0e10cSrcweir const XubString& rGraphicFollowedBy,
813cdf0e10cSrcweir const SvxBrushItem* pGrfBrush,
814cdf0e10cSrcweir const SwFmtVertOrient* pGrfOrient, const Size& rGrfSize,
815cdf0e10cSrcweir const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst,
816cdf0e10cSrcweir const bool bLabelAlignmentPosAndSpaceModeActive ) :
817cdf0e10cSrcweir SwNumberPortion( rGraphicFollowedBy, NULL, bLft, bCntr, nMinDst,
818cdf0e10cSrcweir bLabelAlignmentPosAndSpaceModeActive ),
819cdf0e10cSrcweir // <--
820cdf0e10cSrcweir pBrush( new SvxBrushItem(RES_BACKGROUND) ), nId( 0 )
821cdf0e10cSrcweir {
822cdf0e10cSrcweir SetWhichPor( POR_GRFNUM );
823cdf0e10cSrcweir SetAnimated( sal_False );
824cdf0e10cSrcweir bReplace = sal_False;
825cdf0e10cSrcweir if( pGrfBrush )
826cdf0e10cSrcweir {
827cdf0e10cSrcweir *pBrush = *pGrfBrush;
828cdf0e10cSrcweir const Graphic* pGraph = pGrfBrush->GetGraphic();
829cdf0e10cSrcweir if( pGraph )
830cdf0e10cSrcweir SetAnimated( pGraph->IsAnimated() );
831cdf0e10cSrcweir else
832cdf0e10cSrcweir bReplace = sal_True;
833cdf0e10cSrcweir }
834cdf0e10cSrcweir if( pGrfOrient )
835cdf0e10cSrcweir {
836cdf0e10cSrcweir nYPos = pGrfOrient->GetPos();
837cdf0e10cSrcweir eOrient = pGrfOrient->GetVertOrient();
838cdf0e10cSrcweir }
839cdf0e10cSrcweir else
840cdf0e10cSrcweir {
841cdf0e10cSrcweir nYPos = 0;
842cdf0e10cSrcweir eOrient = text::VertOrientation::TOP;
843cdf0e10cSrcweir }
844cdf0e10cSrcweir Width( static_cast<sal_uInt16>(rGrfSize.Width() + 2 * GRFNUM_SECURE) );
845cdf0e10cSrcweir nFixWidth = Width();
846cdf0e10cSrcweir nGrfHeight = rGrfSize.Height() + 2 * GRFNUM_SECURE;
847cdf0e10cSrcweir Height( KSHORT(nGrfHeight) );
848cdf0e10cSrcweir bNoPaint = sal_False;
849cdf0e10cSrcweir }
850cdf0e10cSrcweir
~SwGrfNumPortion()851cdf0e10cSrcweir SwGrfNumPortion::~SwGrfNumPortion()
852cdf0e10cSrcweir {
853cdf0e10cSrcweir if ( IsAnimated() )
854cdf0e10cSrcweir ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( 0, nId );
855cdf0e10cSrcweir delete pBrush;
856cdf0e10cSrcweir }
857cdf0e10cSrcweir
StopAnimation(OutputDevice * pOut)858cdf0e10cSrcweir void SwGrfNumPortion::StopAnimation( OutputDevice* pOut )
859cdf0e10cSrcweir {
860cdf0e10cSrcweir if ( IsAnimated() )
861cdf0e10cSrcweir ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( pOut, nId );
862cdf0e10cSrcweir }
863cdf0e10cSrcweir
Format(SwTxtFormatInfo & rInf)864cdf0e10cSrcweir sal_Bool SwGrfNumPortion::Format( SwTxtFormatInfo &rInf )
865cdf0e10cSrcweir {
866cdf0e10cSrcweir SetHide( sal_False );
867cdf0e10cSrcweir // --> OD 2008-01-29 #newlistlevelattrs#
868cdf0e10cSrcweir // Width( nFixWidth );
869cdf0e10cSrcweir KSHORT nFollowedByWidth( 0 );
870cdf0e10cSrcweir if ( mbLabelAlignmentPosAndSpaceModeActive )
871cdf0e10cSrcweir {
872cdf0e10cSrcweir SwFldPortion::Format( rInf );
873cdf0e10cSrcweir nFollowedByWidth = Width();
874cdf0e10cSrcweir SetLen( 0 );
875cdf0e10cSrcweir }
876cdf0e10cSrcweir Width( nFixWidth + nFollowedByWidth );
877cdf0e10cSrcweir // <--
878cdf0e10cSrcweir const sal_Bool bFull = rInf.Width() < rInf.X() + Width();
879cdf0e10cSrcweir const sal_Bool bFly = rInf.GetFly() ||
880cdf0e10cSrcweir ( rInf.GetLast() && rInf.GetLast()->IsFlyPortion() );
881cdf0e10cSrcweir SetAscent( static_cast<sal_uInt16>(GetRelPos() > 0 ? GetRelPos() : 0) );
882cdf0e10cSrcweir if( GetAscent() > Height() )
883cdf0e10cSrcweir Height( GetAscent() );
884cdf0e10cSrcweir
885cdf0e10cSrcweir if( bFull )
886cdf0e10cSrcweir {
887cdf0e10cSrcweir Width( rInf.Width() - (KSHORT)rInf.X() );
888cdf0e10cSrcweir if( bFly )
889cdf0e10cSrcweir {
890cdf0e10cSrcweir SetLen( 0 );
891cdf0e10cSrcweir SetNoPaint( sal_True );
892cdf0e10cSrcweir rInf.SetNumDone( sal_False );
893cdf0e10cSrcweir return sal_True;
894cdf0e10cSrcweir }
895cdf0e10cSrcweir }
896cdf0e10cSrcweir rInf.SetNumDone( sal_True );
897cdf0e10cSrcweir // --> OD 2008-01-23 #newlistlevelattrs#
898cdf0e10cSrcweir // long nDiff = rInf.Left() - rInf.First() + rInf.ForcedLeftMargin();
899cdf0e10cSrcweir long nDiff = mbLabelAlignmentPosAndSpaceModeActive
900cdf0e10cSrcweir ? 0
901cdf0e10cSrcweir : rInf.Left() - rInf.First() + rInf.ForcedLeftMargin();
902cdf0e10cSrcweir // <--
903cdf0e10cSrcweir // Ein Vorschlag von Juergen und Volkmar:
904cdf0e10cSrcweir // Der Textteil hinter der Numerierung sollte immer
905cdf0e10cSrcweir // mindestens beim linken Rand beginnen.
906cdf0e10cSrcweir if( nDiff < 0 )
907cdf0e10cSrcweir nDiff = 0;
908cdf0e10cSrcweir else if ( nDiff > rInf.X() )
909cdf0e10cSrcweir nDiff -= rInf.X();
910cdf0e10cSrcweir if( nDiff < nFixWidth + nMinDist )
911cdf0e10cSrcweir nDiff = nFixWidth + nMinDist;
912cdf0e10cSrcweir // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde
913cdf0e10cSrcweir // fieser Sonderfall: FlyFrm liegt in dem Bereich,
914cdf0e10cSrcweir // den wir uns gerade unter den Nagel reissen wollen.
915cdf0e10cSrcweir // Die NumberPortion wird als verborgen markiert.
916cdf0e10cSrcweir if( nDiff > rInf.Width() )
917cdf0e10cSrcweir {
918cdf0e10cSrcweir nDiff = rInf.Width();
919cdf0e10cSrcweir if( bFly )
920cdf0e10cSrcweir SetHide( sal_True );
921cdf0e10cSrcweir }
922cdf0e10cSrcweir
923cdf0e10cSrcweir if( Width() < nDiff )
924cdf0e10cSrcweir Width( KSHORT(nDiff) );
925cdf0e10cSrcweir return bFull;
926cdf0e10cSrcweir }
927cdf0e10cSrcweir
Paint(const SwTxtPaintInfo & rInf) const928cdf0e10cSrcweir void SwGrfNumPortion::Paint( const SwTxtPaintInfo &rInf ) const
929cdf0e10cSrcweir {
930cdf0e10cSrcweir if( DontPaint() )
931cdf0e10cSrcweir return;
932cdf0e10cSrcweir /* Eine verborgene NumberPortion wird nicht angezeigt, es sei denn, es gibt
933cdf0e10cSrcweir * Textportions in dieser Zeile oder es gibt ueberhaupt nur eine einzige Zeile.
934cdf0e10cSrcweir */
935cdf0e10cSrcweir if ( IsHide() && rInf.GetParaPortion() && rInf.GetParaPortion()->GetNext() )
936cdf0e10cSrcweir {
937cdf0e10cSrcweir SwLinePortion *pTmp = GetPortion();
938cdf0e10cSrcweir while ( pTmp && !pTmp->InTxtGrp() )
939cdf0e10cSrcweir pTmp = pTmp->GetPortion();
940cdf0e10cSrcweir if ( !pTmp )
941cdf0e10cSrcweir return;
942cdf0e10cSrcweir }
943cdf0e10cSrcweir Point aPos( rInf.X() + GRFNUM_SECURE, rInf.Y() - GetRelPos() + GRFNUM_SECURE );
944cdf0e10cSrcweir long nTmpWidth = Max( (long)0, (long)(nFixWidth - 2 * GRFNUM_SECURE) );
945cdf0e10cSrcweir Size aSize( nTmpWidth, GetGrfHeight() - 2 * GRFNUM_SECURE );
946cdf0e10cSrcweir
947cdf0e10cSrcweir // --> OD 2008-02-05 #newlistlevelattrs#
948cdf0e10cSrcweir const sal_Bool bTmpLeft = mbLabelAlignmentPosAndSpaceModeActive ||
949cdf0e10cSrcweir ( IsLeft() && ! rInf.GetTxtFrm()->IsRightToLeft() ) ||
950cdf0e10cSrcweir ( ! IsLeft() && ! IsCenter() && rInf.GetTxtFrm()->IsRightToLeft() );
951cdf0e10cSrcweir // <--
952cdf0e10cSrcweir
953cdf0e10cSrcweir if( nFixWidth < Width() && !bTmpLeft )
954cdf0e10cSrcweir {
955cdf0e10cSrcweir KSHORT nOffset = Width() - nFixWidth;
956cdf0e10cSrcweir if( nOffset < nMinDist )
957cdf0e10cSrcweir nOffset = 0;
958cdf0e10cSrcweir else
959cdf0e10cSrcweir {
960cdf0e10cSrcweir if( IsCenter() )
961cdf0e10cSrcweir {
962cdf0e10cSrcweir nOffset /= 2;
963cdf0e10cSrcweir if( nOffset < nMinDist )
964cdf0e10cSrcweir nOffset = Width() - nFixWidth - nMinDist;
965cdf0e10cSrcweir }
966cdf0e10cSrcweir else
967cdf0e10cSrcweir nOffset = nOffset - nMinDist;
968cdf0e10cSrcweir }
969cdf0e10cSrcweir aPos.X() += nOffset;
970cdf0e10cSrcweir }
971cdf0e10cSrcweir
972cdf0e10cSrcweir if( bReplace )
973cdf0e10cSrcweir {
974cdf0e10cSrcweir KSHORT nTmpH = GetPortion() ? GetPortion()->GetAscent() : 120;
975cdf0e10cSrcweir aSize = Size( nTmpH, nTmpH );
976cdf0e10cSrcweir aPos.Y() = rInf.Y() - nTmpH;
977cdf0e10cSrcweir }
978cdf0e10cSrcweir SwRect aTmp( aPos, aSize );
979cdf0e10cSrcweir
980cdf0e10cSrcweir sal_Bool bDraw = sal_True;
981cdf0e10cSrcweir
982cdf0e10cSrcweir if ( IsAnimated() )
983cdf0e10cSrcweir {
984cdf0e10cSrcweir bDraw = !rInf.GetOpt().IsGraphic();
985cdf0e10cSrcweir if( !nId )
986cdf0e10cSrcweir {
987cdf0e10cSrcweir SetId( long( rInf.GetTxtFrm() ) );
988cdf0e10cSrcweir rInf.GetTxtFrm()->SetAnimation();
989cdf0e10cSrcweir }
990cdf0e10cSrcweir if( aTmp.IsOver( rInf.GetPaintRect() ) && !bDraw )
991cdf0e10cSrcweir {
992cdf0e10cSrcweir rInf.NoteAnimation();
993cdf0e10cSrcweir const ViewShell* pViewShell = rInf.GetVsh();
994cdf0e10cSrcweir
995cdf0e10cSrcweir // virtual device, not pdf export
996cdf0e10cSrcweir if( OUTDEV_VIRDEV == rInf.GetOut()->GetOutDevType() &&
997cdf0e10cSrcweir pViewShell && pViewShell->GetWin() )
998cdf0e10cSrcweir {
999cdf0e10cSrcweir ( (Graphic*) pBrush->GetGraphic() )->StopAnimation(0,nId);
1000cdf0e10cSrcweir rInf.GetTxtFrm()->getRootFrm()->GetCurrShell()->InvalidateWindows( aTmp );
1001cdf0e10cSrcweir }
1002cdf0e10cSrcweir
1003cdf0e10cSrcweir
1004cdf0e10cSrcweir else if ( pViewShell &&
1005cdf0e10cSrcweir !pViewShell->GetAccessibilityOptions()->IsStopAnimatedGraphics() &&
1006cdf0e10cSrcweir !pViewShell->IsPreView() &&
1007cdf0e10cSrcweir // --> FME 2004-06-21 #i9684# Stop animation during printing/pdf export.
1008cdf0e10cSrcweir pViewShell->GetWin() )
1009cdf0e10cSrcweir // <--
1010cdf0e10cSrcweir {
1011cdf0e10cSrcweir ( (Graphic*) pBrush->GetGraphic() )->StartAnimation(
1012cdf0e10cSrcweir (OutputDevice*)rInf.GetOut(), aPos, aSize, nId );
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir
1015cdf0e10cSrcweir // pdf export, printing, preview, stop animations...
1016cdf0e10cSrcweir else
1017cdf0e10cSrcweir bDraw = sal_True;
1018cdf0e10cSrcweir }
1019cdf0e10cSrcweir if( bDraw )
1020cdf0e10cSrcweir ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( 0, nId );
1021cdf0e10cSrcweir }
1022cdf0e10cSrcweir
1023cdf0e10cSrcweir SwRect aRepaint( rInf.GetPaintRect() );
1024cdf0e10cSrcweir const SwTxtFrm& rFrm = *rInf.GetTxtFrm();
1025cdf0e10cSrcweir if( rFrm.IsVertical() )
1026cdf0e10cSrcweir {
1027cdf0e10cSrcweir rFrm.SwitchHorizontalToVertical( aTmp );
1028cdf0e10cSrcweir rFrm.SwitchHorizontalToVertical( aRepaint );
1029cdf0e10cSrcweir }
1030cdf0e10cSrcweir
1031cdf0e10cSrcweir if( rFrm.IsRightToLeft() )
1032cdf0e10cSrcweir {
1033cdf0e10cSrcweir rFrm.SwitchLTRtoRTL( aTmp );
1034cdf0e10cSrcweir rFrm.SwitchLTRtoRTL( aRepaint );
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir
1037cdf0e10cSrcweir if( bDraw && aTmp.HasArea() )
103864b14621SArmin Le Grand {
1039cdf0e10cSrcweir DrawGraphic( pBrush, (OutputDevice*)rInf.GetOut(),
1040cdf0e10cSrcweir aTmp, aRepaint, bReplace ? GRFNUM_REPLACE : GRFNUM_YES );
1041cdf0e10cSrcweir }
104264b14621SArmin Le Grand }
1043cdf0e10cSrcweir
SetBase(long nLnAscent,long nLnDescent,long nFlyAsc,long nFlyDesc)1044cdf0e10cSrcweir void SwGrfNumPortion::SetBase( long nLnAscent, long nLnDescent,
1045cdf0e10cSrcweir long nFlyAsc, long nFlyDesc )
1046cdf0e10cSrcweir {
1047cdf0e10cSrcweir if ( GetOrient() != text::VertOrientation::NONE )
1048cdf0e10cSrcweir {
1049cdf0e10cSrcweir SetRelPos( 0 );
1050cdf0e10cSrcweir if ( GetOrient() == text::VertOrientation::CENTER )
1051cdf0e10cSrcweir SetRelPos( GetGrfHeight() / 2 );
1052cdf0e10cSrcweir else if ( GetOrient() == text::VertOrientation::TOP )
1053cdf0e10cSrcweir SetRelPos( GetGrfHeight() - GRFNUM_SECURE );
1054cdf0e10cSrcweir else if ( GetOrient() == text::VertOrientation::BOTTOM )
1055cdf0e10cSrcweir ;
1056cdf0e10cSrcweir else if ( GetOrient() == text::VertOrientation::CHAR_CENTER )
1057cdf0e10cSrcweir SetRelPos( ( GetGrfHeight() + nLnAscent - nLnDescent ) / 2 );
1058cdf0e10cSrcweir else if ( GetOrient() == text::VertOrientation::CHAR_TOP )
1059cdf0e10cSrcweir SetRelPos( nLnAscent );
1060cdf0e10cSrcweir else if ( GetOrient() == text::VertOrientation::CHAR_BOTTOM )
1061cdf0e10cSrcweir SetRelPos( GetGrfHeight() - nLnDescent );
1062cdf0e10cSrcweir else
1063cdf0e10cSrcweir {
1064cdf0e10cSrcweir if( GetGrfHeight() >= nFlyAsc + nFlyDesc )
1065cdf0e10cSrcweir {
1066cdf0e10cSrcweir // wenn ich genauso gross bin wie die Zeile, brauche ich mich
1067cdf0e10cSrcweir // nicht an der Zeile nicht weiter ausrichten, ich lasse
1068cdf0e10cSrcweir // dann auch den max. Ascent der Zeile unveraendert
1069cdf0e10cSrcweir
1070cdf0e10cSrcweir SetRelPos( nFlyAsc );
1071cdf0e10cSrcweir }
1072cdf0e10cSrcweir else if ( GetOrient() == text::VertOrientation::LINE_CENTER )
1073cdf0e10cSrcweir SetRelPos( ( GetGrfHeight() + nFlyAsc - nFlyDesc ) / 2 );
1074cdf0e10cSrcweir else if ( GetOrient() == text::VertOrientation::LINE_TOP )
1075cdf0e10cSrcweir SetRelPos( nFlyAsc );
1076cdf0e10cSrcweir else if ( GetOrient() == text::VertOrientation::LINE_BOTTOM )
1077cdf0e10cSrcweir SetRelPos( GetGrfHeight() - nFlyDesc );
1078cdf0e10cSrcweir }
1079cdf0e10cSrcweir }
1080cdf0e10cSrcweir }
1081cdf0e10cSrcweir
StopAnimation(OutputDevice * pOut)1082cdf0e10cSrcweir void SwTxtFrm::StopAnimation( OutputDevice* pOut )
1083cdf0e10cSrcweir {
1084cdf0e10cSrcweir ASSERT( HasAnimation(), "SwTxtFrm::StopAnimation: Which Animation?" );
1085cdf0e10cSrcweir if( HasPara() )
1086cdf0e10cSrcweir {
1087cdf0e10cSrcweir SwLineLayout *pLine = GetPara();
1088cdf0e10cSrcweir while( pLine )
1089cdf0e10cSrcweir {
1090cdf0e10cSrcweir SwLinePortion *pPor = pLine->GetPortion();
1091cdf0e10cSrcweir while( pPor )
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir if( pPor->IsGrfNumPortion() )
1094cdf0e10cSrcweir ((SwGrfNumPortion*)pPor)->StopAnimation( pOut );
1095cdf0e10cSrcweir // Die Numerierungsportion sitzt immer vor dem ersten Zeichen,
1096cdf0e10cSrcweir // deshalb koennen wir abbrechen, sobald wir eine Portion mit
1097cdf0e10cSrcweir // einer Laenge > 0 erreicht haben.
1098cdf0e10cSrcweir pPor = pPor->GetLen() ? 0 : pPor->GetPortion();
1099cdf0e10cSrcweir }
1100cdf0e10cSrcweir pLine = pLine->GetLen() ? 0 : pLine->GetNext();
1101cdf0e10cSrcweir }
1102cdf0e10cSrcweir }
1103cdf0e10cSrcweir }
1104cdf0e10cSrcweir
1105cdf0e10cSrcweir /*************************************************************************
1106cdf0e10cSrcweir * SwCombinedPortion::SwCombinedPortion(..)
1107cdf0e10cSrcweir * initializes the script array and clears the width array
1108cdf0e10cSrcweir *************************************************************************/
1109cdf0e10cSrcweir
SwCombinedPortion(const XubString & rTxt)1110cdf0e10cSrcweir SwCombinedPortion::SwCombinedPortion( const XubString &rTxt )
1111cdf0e10cSrcweir : SwFldPortion( rTxt )
1112cdf0e10cSrcweir {
1113cdf0e10cSrcweir SetLen(1);
1114cdf0e10cSrcweir SetWhichPor( POR_COMBINED );
1115cdf0e10cSrcweir if( aExpand.Len() > 6 )
1116cdf0e10cSrcweir aExpand.Erase( 6 );
1117cdf0e10cSrcweir // Initialization of the scripttype array,
1118cdf0e10cSrcweir // the arrays of width and position are filled by the format function
1119cdf0e10cSrcweir if( pBreakIt->GetBreakIter().is() )
1120cdf0e10cSrcweir {
1121cdf0e10cSrcweir sal_uInt8 nScr = SW_SCRIPTS;
1122cdf0e10cSrcweir for( sal_uInt16 i = 0; i < rTxt.Len(); ++i )
1123cdf0e10cSrcweir {
1124cdf0e10cSrcweir sal_uInt16 nScript = pBreakIt->GetBreakIter()->getScriptType( rTxt, i );
1125cdf0e10cSrcweir switch ( nScript ) {
1126cdf0e10cSrcweir case i18n::ScriptType::LATIN : nScr = SW_LATIN; break;
1127cdf0e10cSrcweir case i18n::ScriptType::ASIAN : nScr = SW_CJK; break;
1128cdf0e10cSrcweir case i18n::ScriptType::COMPLEX : nScr = SW_CTL; break;
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir aScrType[i] = nScr;
1131cdf0e10cSrcweir }
1132cdf0e10cSrcweir }
1133cdf0e10cSrcweir else
1134cdf0e10cSrcweir {
1135cdf0e10cSrcweir for( sal_uInt16 i = 0; i < 6; aScrType[i++] = 0 )
1136cdf0e10cSrcweir ; // nothing
1137cdf0e10cSrcweir }
1138cdf0e10cSrcweir memset( &aWidth, 0, sizeof(aWidth) );
1139cdf0e10cSrcweir }
1140cdf0e10cSrcweir
1141cdf0e10cSrcweir /*************************************************************************
1142cdf0e10cSrcweir * SwCombinedPortion::Paint(..)
1143cdf0e10cSrcweir *************************************************************************/
1144cdf0e10cSrcweir
Paint(const SwTxtPaintInfo & rInf) const1145cdf0e10cSrcweir void SwCombinedPortion::Paint( const SwTxtPaintInfo &rInf ) const
1146cdf0e10cSrcweir {
1147*86e1cf34SPedro Giffuni ASSERT( GetLen() <= 1, "SwFldPortion::Paint: rest-portion pollution?" );
1148cdf0e10cSrcweir if( Width() )
1149cdf0e10cSrcweir {
1150cdf0e10cSrcweir rInf.DrawBackBrush( *this );
1151cdf0e10cSrcweir rInf.DrawViewOpt( *this, POR_FLD );
1152cdf0e10cSrcweir
1153cdf0e10cSrcweir // do we have to repaint a post it portion?
1154cdf0e10cSrcweir if( rInf.OnWin() && pPortion && !pPortion->Width() )
1155cdf0e10cSrcweir pPortion->PrePaint( rInf, this );
1156cdf0e10cSrcweir
1157cdf0e10cSrcweir sal_uInt16 nCount = aExpand.Len();
1158cdf0e10cSrcweir if( !nCount )
1159cdf0e10cSrcweir return;
1160cdf0e10cSrcweir ASSERT( nCount < 7, "Too much combined characters" );
1161cdf0e10cSrcweir
1162cdf0e10cSrcweir // the first character of the second row
1163cdf0e10cSrcweir sal_uInt16 nTop = ( nCount + 1 ) / 2;
1164cdf0e10cSrcweir
1165cdf0e10cSrcweir SwFont aTmpFont( *rInf.GetFont() );
1166cdf0e10cSrcweir aTmpFont.SetProportion( nProportion ); // a smaller font
1167cdf0e10cSrcweir SwFontSave aFontSave( rInf, &aTmpFont );
1168cdf0e10cSrcweir
1169cdf0e10cSrcweir sal_uInt16 i = 0;
1170cdf0e10cSrcweir Point aOldPos = rInf.GetPos();
1171cdf0e10cSrcweir Point aOutPos( aOldPos.X(), aOldPos.Y() - nUpPos );// Y of the first row
1172cdf0e10cSrcweir while( i < nCount )
1173cdf0e10cSrcweir {
1174cdf0e10cSrcweir if( i == nTop ) // change the row
1175cdf0e10cSrcweir aOutPos.Y() = aOldPos.Y() + nLowPos; // Y of the second row
1176cdf0e10cSrcweir aOutPos.X() = aOldPos.X() + aPos[i]; // X position
1177cdf0e10cSrcweir const sal_uInt8 nAct = aScrType[i]; // script type
1178cdf0e10cSrcweir aTmpFont.SetActual( nAct );
1179cdf0e10cSrcweir // if there're more than 4 characters to display, we choose fonts
1180cdf0e10cSrcweir // with 2/3 of the original font width.
1181cdf0e10cSrcweir if( aWidth[ nAct ] )
1182cdf0e10cSrcweir {
1183cdf0e10cSrcweir Size aTmpSz = aTmpFont.GetSize( nAct );
1184cdf0e10cSrcweir if( aTmpSz.Width() != aWidth[ nAct ] )
1185cdf0e10cSrcweir {
1186cdf0e10cSrcweir aTmpSz.Width() = aWidth[ nAct ];
1187cdf0e10cSrcweir aTmpFont.SetSize( aTmpSz, nAct );
1188cdf0e10cSrcweir }
1189cdf0e10cSrcweir }
1190cdf0e10cSrcweir ((SwTxtPaintInfo&)rInf).SetPos( aOutPos );
1191cdf0e10cSrcweir rInf.DrawText( aExpand, *this, i, 1 );
1192cdf0e10cSrcweir ++i;
1193cdf0e10cSrcweir }
1194cdf0e10cSrcweir // rInf is const, so we have to take back our manipulations
1195cdf0e10cSrcweir ((SwTxtPaintInfo&)rInf).SetPos( aOldPos );
1196cdf0e10cSrcweir }
1197cdf0e10cSrcweir }
1198cdf0e10cSrcweir
1199cdf0e10cSrcweir /*************************************************************************
1200cdf0e10cSrcweir * SwCombinedPortion::Format(..)
1201cdf0e10cSrcweir *************************************************************************/
1202cdf0e10cSrcweir
Format(SwTxtFormatInfo & rInf)1203cdf0e10cSrcweir sal_Bool SwCombinedPortion::Format( SwTxtFormatInfo &rInf )
1204cdf0e10cSrcweir {
1205cdf0e10cSrcweir sal_uInt16 nCount = aExpand.Len();
1206cdf0e10cSrcweir if( !nCount )
1207cdf0e10cSrcweir {
1208cdf0e10cSrcweir Width( 0 );
1209cdf0e10cSrcweir return sal_False;
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir
1212cdf0e10cSrcweir ASSERT( nCount < 7, "Too much combined characters" );
1213cdf0e10cSrcweir // If there are leading "weak"-scripttyped characters in this portion,
1214cdf0e10cSrcweir // they get the actual scripttype.
1215cdf0e10cSrcweir sal_uInt16 i = 0;
1216cdf0e10cSrcweir while( i < nCount && SW_SCRIPTS == aScrType[i] )
1217cdf0e10cSrcweir aScrType[i++] = rInf.GetFont()->GetActual();
1218cdf0e10cSrcweir if( nCount > 4 )
1219cdf0e10cSrcweir {
1220cdf0e10cSrcweir // more than four? Ok, then we need the 2/3 font width
1221cdf0e10cSrcweir i = 0;
1222cdf0e10cSrcweir while( i < aExpand.Len() )
1223cdf0e10cSrcweir {
1224cdf0e10cSrcweir ASSERT( aScrType[i] < SW_SCRIPTS, "Combined: Script fault" );
1225cdf0e10cSrcweir if( !aWidth[ aScrType[i] ] )
1226cdf0e10cSrcweir {
1227cdf0e10cSrcweir rInf.GetOut()->SetFont( rInf.GetFont()->GetFnt( aScrType[i] ) );
1228cdf0e10cSrcweir aWidth[ aScrType[i] ] =
1229cdf0e10cSrcweir static_cast<sal_uInt16>(2 * rInf.GetOut()->GetFontMetric().GetSize().Width() / 3);
1230cdf0e10cSrcweir }
1231cdf0e10cSrcweir ++i;
1232cdf0e10cSrcweir }
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir
1235cdf0e10cSrcweir sal_uInt16 nTop = ( nCount + 1 ) / 2; // the first character of the second line
1236cdf0e10cSrcweir ViewShell *pSh = rInf.GetTxtFrm()->getRootFrm()->GetCurrShell();
1237cdf0e10cSrcweir SwFont aTmpFont( *rInf.GetFont() );
1238cdf0e10cSrcweir SwFontSave aFontSave( rInf, &aTmpFont );
1239cdf0e10cSrcweir nProportion = 55;
1240cdf0e10cSrcweir // In nMainAscent/Descent we store the ascent and descent
1241cdf0e10cSrcweir // of the original surrounding font
1242cdf0e10cSrcweir sal_uInt16 nMaxDescent, nMaxAscent, nMaxWidth;
1243cdf0e10cSrcweir sal_uInt16 nMainDescent = rInf.GetFont()->GetHeight( pSh, *rInf.GetOut() );
1244cdf0e10cSrcweir const sal_uInt16 nMainAscent = rInf.GetFont()->GetAscent( pSh, *rInf.GetOut() );
1245cdf0e10cSrcweir nMainDescent = nMainDescent - nMainAscent;
1246cdf0e10cSrcweir // we start with a 50% font, but if we notice that the combined portion
1247cdf0e10cSrcweir // becomes bigger than the surrounding font, we check 45% and maybe 40%.
1248cdf0e10cSrcweir do
1249cdf0e10cSrcweir {
1250cdf0e10cSrcweir nProportion -= 5;
1251cdf0e10cSrcweir aTmpFont.SetProportion( nProportion );
1252cdf0e10cSrcweir i = 0;
1253cdf0e10cSrcweir memset( &aPos, 0, sizeof(aPos) );
1254cdf0e10cSrcweir nMaxDescent = 0;
1255cdf0e10cSrcweir nMaxAscent = 0;
1256cdf0e10cSrcweir nMaxWidth = 0;
1257cdf0e10cSrcweir nUpPos = nLowPos = 0;
1258cdf0e10cSrcweir
1259cdf0e10cSrcweir // Now we get the width of all characters.
1260cdf0e10cSrcweir // The ascent and the width of the first line are stored in the
1261cdf0e10cSrcweir // ascent member of the portion, the descent in nLowPos.
1262cdf0e10cSrcweir // The ascent, descent and width of the second line are stored in the
1263cdf0e10cSrcweir // local nMaxAscent, nMaxDescent and nMaxWidth variables.
1264cdf0e10cSrcweir while( i < nCount )
1265cdf0e10cSrcweir {
1266cdf0e10cSrcweir sal_uInt8 nScrp = aScrType[i];
1267cdf0e10cSrcweir aTmpFont.SetActual( nScrp );
1268cdf0e10cSrcweir if( aWidth[ nScrp ] )
1269cdf0e10cSrcweir {
1270cdf0e10cSrcweir Size aFontSize( aTmpFont.GetSize( nScrp ) );
1271cdf0e10cSrcweir aFontSize.Width() = aWidth[ nScrp ];
1272cdf0e10cSrcweir aTmpFont.SetSize( aFontSize, nScrp );
1273cdf0e10cSrcweir }
1274cdf0e10cSrcweir
1275cdf0e10cSrcweir SwDrawTextInfo aDrawInf( pSh, *rInf.GetOut(), 0, aExpand, i, 1 );
1276cdf0e10cSrcweir Size aSize = aTmpFont._GetTxtSize( aDrawInf );
1277cdf0e10cSrcweir sal_uInt16 nAsc = aTmpFont.GetAscent( pSh, *rInf.GetOut() );
1278cdf0e10cSrcweir aPos[ i ] = (sal_uInt16)aSize.Width();
1279cdf0e10cSrcweir if( i == nTop ) // enter the second line
1280cdf0e10cSrcweir {
1281cdf0e10cSrcweir nLowPos = nMaxDescent;
1282cdf0e10cSrcweir Height( nMaxDescent + nMaxAscent );
1283cdf0e10cSrcweir Width( nMaxWidth );
1284cdf0e10cSrcweir SetAscent( nMaxAscent );
1285cdf0e10cSrcweir nMaxAscent = 0;
1286cdf0e10cSrcweir nMaxDescent = 0;
1287cdf0e10cSrcweir nMaxWidth = 0;
1288cdf0e10cSrcweir }
1289cdf0e10cSrcweir nMaxWidth = nMaxWidth + aPos[ i++ ];
1290cdf0e10cSrcweir if( nAsc > nMaxAscent )
1291cdf0e10cSrcweir nMaxAscent = nAsc;
1292cdf0e10cSrcweir if( aSize.Height() - nAsc > nMaxDescent )
1293cdf0e10cSrcweir nMaxDescent = static_cast<sal_uInt16>(aSize.Height() - nAsc);
1294cdf0e10cSrcweir }
1295cdf0e10cSrcweir // for one or two characters we double the width of the portion
1296cdf0e10cSrcweir if( nCount < 3 )
1297cdf0e10cSrcweir {
1298cdf0e10cSrcweir nMaxWidth *= 2;
1299cdf0e10cSrcweir Width( 2*Width() );
1300cdf0e10cSrcweir if( nCount < 2 )
1301cdf0e10cSrcweir {
1302cdf0e10cSrcweir Height( nMaxAscent + nMaxDescent );
1303cdf0e10cSrcweir nLowPos = nMaxDescent;
1304cdf0e10cSrcweir }
1305cdf0e10cSrcweir }
1306cdf0e10cSrcweir Height( Height() + nMaxDescent + nMaxAscent );
1307cdf0e10cSrcweir nUpPos = nMaxAscent;
1308cdf0e10cSrcweir SetAscent( Height() - nMaxDescent - nLowPos );
1309cdf0e10cSrcweir } while( nProportion > 40 && ( GetAscent() > nMainAscent ||
1310cdf0e10cSrcweir Height() - GetAscent() > nMainDescent ) );
1311cdf0e10cSrcweir // if the combined portion is smaller than the surrounding text,
1312cdf0e10cSrcweir // the portion grows. This looks better, if there's a character background.
1313cdf0e10cSrcweir if( GetAscent() < nMainAscent )
1314cdf0e10cSrcweir {
1315cdf0e10cSrcweir Height( Height() + nMainAscent - GetAscent() );
1316cdf0e10cSrcweir SetAscent( nMainAscent );
1317cdf0e10cSrcweir }
1318cdf0e10cSrcweir if( Height() < nMainAscent + nMainDescent )
1319cdf0e10cSrcweir Height( nMainAscent + nMainDescent );
1320cdf0e10cSrcweir
1321cdf0e10cSrcweir // We calculate the x positions of the characters in both lines..
1322cdf0e10cSrcweir sal_uInt16 nTopDiff = 0;
1323cdf0e10cSrcweir sal_uInt16 nBotDiff = 0;
1324cdf0e10cSrcweir if( nMaxWidth > Width() )
1325cdf0e10cSrcweir {
1326cdf0e10cSrcweir nTopDiff = ( nMaxWidth - Width() ) / 2;
1327cdf0e10cSrcweir Width( nMaxWidth );
1328cdf0e10cSrcweir }
1329cdf0e10cSrcweir else
1330cdf0e10cSrcweir nBotDiff = ( Width() - nMaxWidth ) / 2;
1331cdf0e10cSrcweir switch( nTop)
1332cdf0e10cSrcweir {
1333cdf0e10cSrcweir case 3: aPos[1] = aPos[0] + nTopDiff; // no break
1334cdf0e10cSrcweir case 2: aPos[nTop-1] = Width() - aPos[nTop-1];
1335cdf0e10cSrcweir }
1336cdf0e10cSrcweir aPos[0] = 0;
1337cdf0e10cSrcweir switch( nCount )
1338cdf0e10cSrcweir {
1339cdf0e10cSrcweir case 5: aPos[4] = aPos[3] + nBotDiff; // no break
1340cdf0e10cSrcweir case 3: aPos[nTop] = nBotDiff; break;
1341cdf0e10cSrcweir case 6: aPos[4] = aPos[3] + nBotDiff; // no break
1342cdf0e10cSrcweir case 4: aPos[nTop] = 0; // no break
1343cdf0e10cSrcweir case 2: aPos[nCount-1] = Width() - aPos[nCount-1];
1344cdf0e10cSrcweir }
1345cdf0e10cSrcweir
1346cdf0e10cSrcweir // Does the combined portion fit the line?
1347cdf0e10cSrcweir const sal_Bool bFull = rInf.Width() < rInf.X() + Width();
1348cdf0e10cSrcweir if( bFull )
1349cdf0e10cSrcweir {
1350cdf0e10cSrcweir if( rInf.GetLineStart() == rInf.GetIdx() && (!rInf.GetLast()->InFldGrp()
1351cdf0e10cSrcweir || !((SwFldPortion*)rInf.GetLast())->IsFollow() ) )
1352cdf0e10cSrcweir Width( (sal_uInt16)( rInf.Width() - rInf.X() ) );
1353cdf0e10cSrcweir else
1354cdf0e10cSrcweir {
1355cdf0e10cSrcweir Truncate();
1356cdf0e10cSrcweir Width( 0 );
1357cdf0e10cSrcweir SetLen( 0 );
1358cdf0e10cSrcweir if( rInf.GetLast() )
1359cdf0e10cSrcweir rInf.GetLast()->FormatEOL( rInf );
1360cdf0e10cSrcweir }
1361cdf0e10cSrcweir }
1362cdf0e10cSrcweir return bFull;
1363cdf0e10cSrcweir }
1364cdf0e10cSrcweir
1365cdf0e10cSrcweir /*************************************************************************
1366cdf0e10cSrcweir * SwCombinedPortion::GetViewWidth(..)
1367cdf0e10cSrcweir *************************************************************************/
1368cdf0e10cSrcweir
GetViewWidth(const SwTxtSizeInfo & rInf) const1369cdf0e10cSrcweir KSHORT SwCombinedPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
1370cdf0e10cSrcweir {
1371cdf0e10cSrcweir if( !GetLen() ) // for the dummy part at the end of the line, where
1372cdf0e10cSrcweir return 0; // the combined portion doesn't fit.
1373cdf0e10cSrcweir return SwFldPortion::GetViewWidth( rInf );
1374cdf0e10cSrcweir }
1375