1*efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*efeef26fSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*efeef26fSAndrew Rist * distributed with this work for additional information
6*efeef26fSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*efeef26fSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*efeef26fSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*efeef26fSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist * KIND, either express or implied. See the License for the
17*efeef26fSAndrew Rist * specific language governing permissions and limitations
18*efeef26fSAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*efeef26fSAndrew Rist *************************************************************/
21*efeef26fSAndrew Rist
22*efeef26fSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include "ndtxt.hxx"
29cdf0e10cSrcweir #include "flyfrm.hxx"
30cdf0e10cSrcweir #include "paratr.hxx"
31cdf0e10cSrcweir #include "errhdl.hxx"
32cdf0e10cSrcweir #include <vcl/outdev.hxx>
33cdf0e10cSrcweir #include <editeng/paravertalignitem.hxx>
34cdf0e10cSrcweir
35cdf0e10cSrcweir #include "pormulti.hxx"
36cdf0e10cSrcweir #include <pagefrm.hxx>
37cdf0e10cSrcweir #include <pagedesc.hxx> // SwPageDesc
38cdf0e10cSrcweir #include <tgrditem.hxx>
39cdf0e10cSrcweir #include <porfld.hxx>
40cdf0e10cSrcweir
41cdf0e10cSrcweir #include "txtcfg.hxx"
42cdf0e10cSrcweir #include "itrtxt.hxx"
43cdf0e10cSrcweir #include "txtfrm.hxx"
44cdf0e10cSrcweir #include "porfly.hxx"
45cdf0e10cSrcweir
46cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
47cdf0e10cSrcweir # include "txtfrm.hxx" // GetFrmID,
48cdf0e10cSrcweir #endif
49cdf0e10cSrcweir
50cdf0e10cSrcweir /*************************************************************************
51cdf0e10cSrcweir * SwTxtIter::CtorInitTxtIter()
52cdf0e10cSrcweir *************************************************************************/
53cdf0e10cSrcweir
CtorInitTxtIter(SwTxtFrm * pNewFrm,SwTxtInfo * pNewInf)54cdf0e10cSrcweir void SwTxtIter::CtorInitTxtIter( SwTxtFrm *pNewFrm, SwTxtInfo *pNewInf )
55cdf0e10cSrcweir {
56cdf0e10cSrcweir #ifdef DBGTXT
57cdf0e10cSrcweir // nStopAt laesst sich vom CV bearbeiten.
58cdf0e10cSrcweir static MSHORT nStopAt = 0;
59cdf0e10cSrcweir if( nStopAt == pNewFrm->GetFrmId() )
60cdf0e10cSrcweir {
61cdf0e10cSrcweir int i = pNewFrm->GetFrmId();
62cdf0e10cSrcweir }
63cdf0e10cSrcweir #endif
64cdf0e10cSrcweir
65cdf0e10cSrcweir SwTxtNode *pNode = pNewFrm->GetTxtNode();
66cdf0e10cSrcweir
67cdf0e10cSrcweir ASSERT( pNewFrm->GetPara(), "No paragraph" );
68cdf0e10cSrcweir
69cdf0e10cSrcweir CtorInitAttrIter( *pNode, pNewFrm->GetPara()->GetScriptInfo(), pNewFrm );
70cdf0e10cSrcweir
71cdf0e10cSrcweir pFrm = pNewFrm;
72cdf0e10cSrcweir pInf = pNewInf;
73cdf0e10cSrcweir // --> OD 2008-01-17 #newlistlevelattrs#
74cdf0e10cSrcweir aLineInf.CtorInitLineInfo( pNode->GetSwAttrSet(), *pNode );
75cdf0e10cSrcweir // <--
76cdf0e10cSrcweir nFrameStart = pFrm->Frm().Pos().Y() + pFrm->Prt().Pos().Y();
77cdf0e10cSrcweir SwTxtIter::Init();
78cdf0e10cSrcweir if( pNode->GetSwAttrSet().GetRegister().GetValue() )
79cdf0e10cSrcweir bRegisterOn = pFrm->FillRegister( nRegStart, nRegDiff );
80cdf0e10cSrcweir else
81cdf0e10cSrcweir bRegisterOn = sal_False;
82cdf0e10cSrcweir }
83cdf0e10cSrcweir
84cdf0e10cSrcweir /*************************************************************************
85cdf0e10cSrcweir * SwTxtIter::Init()
86cdf0e10cSrcweir *************************************************************************/
87cdf0e10cSrcweir
Init()88cdf0e10cSrcweir void SwTxtIter::Init()
89cdf0e10cSrcweir {
90cdf0e10cSrcweir pCurr = pInf->GetParaPortion();
91cdf0e10cSrcweir nStart = pInf->GetTxtStart();
92cdf0e10cSrcweir nY = nFrameStart;
93cdf0e10cSrcweir bPrev = sal_True;
94cdf0e10cSrcweir pPrev = 0;
95cdf0e10cSrcweir nLineNr = 1;
96cdf0e10cSrcweir }
97cdf0e10cSrcweir
98cdf0e10cSrcweir /*************************************************************************
99cdf0e10cSrcweir * SwTxtIter::_GetHeightAndAscent()
100cdf0e10cSrcweir *************************************************************************/
101cdf0e10cSrcweir
CalcAscentAndHeight(KSHORT & rAscent,KSHORT & rHeight) const102cdf0e10cSrcweir void SwTxtIter::CalcAscentAndHeight( KSHORT &rAscent, KSHORT &rHeight ) const
103cdf0e10cSrcweir {
104cdf0e10cSrcweir rHeight = GetLineHeight();
105cdf0e10cSrcweir rAscent = pCurr->GetAscent() + rHeight - pCurr->Height();
106cdf0e10cSrcweir }
107cdf0e10cSrcweir
108cdf0e10cSrcweir /*************************************************************************
109cdf0e10cSrcweir * SwTxtIter::_GetPrev()
110cdf0e10cSrcweir *************************************************************************/
111cdf0e10cSrcweir
_GetPrev()112cdf0e10cSrcweir SwLineLayout *SwTxtIter::_GetPrev()
113cdf0e10cSrcweir {
114cdf0e10cSrcweir pPrev = 0;
115cdf0e10cSrcweir bPrev = sal_True;
116cdf0e10cSrcweir SwLineLayout *pLay = pInf->GetParaPortion();
117cdf0e10cSrcweir if( pCurr == pLay )
118cdf0e10cSrcweir return 0;
119cdf0e10cSrcweir while( pLay->GetNext() != pCurr )
120cdf0e10cSrcweir pLay = pLay->GetNext();
121cdf0e10cSrcweir return pPrev = pLay;
122cdf0e10cSrcweir }
123cdf0e10cSrcweir
124cdf0e10cSrcweir /*************************************************************************
125cdf0e10cSrcweir * SwTxtIter::GetPrev()
126cdf0e10cSrcweir *************************************************************************/
127cdf0e10cSrcweir
GetPrev()128cdf0e10cSrcweir const SwLineLayout *SwTxtIter::GetPrev()
129cdf0e10cSrcweir {
130cdf0e10cSrcweir if(! bPrev)
131cdf0e10cSrcweir _GetPrev();
132cdf0e10cSrcweir return pPrev;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir
135cdf0e10cSrcweir /*************************************************************************
136cdf0e10cSrcweir * SwTxtIter::Prev()
137cdf0e10cSrcweir *************************************************************************/
138cdf0e10cSrcweir
Prev()139cdf0e10cSrcweir const SwLineLayout *SwTxtIter::Prev()
140cdf0e10cSrcweir {
141cdf0e10cSrcweir if( !bPrev )
142cdf0e10cSrcweir _GetPrev();
143cdf0e10cSrcweir if( pPrev )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir bPrev = sal_False;
146cdf0e10cSrcweir pCurr = pPrev;
147cdf0e10cSrcweir nStart = nStart - pCurr->GetLen();
148cdf0e10cSrcweir nY = nY - GetLineHeight();
149cdf0e10cSrcweir if( !pCurr->IsDummy() && !(--nLineNr) )
150cdf0e10cSrcweir ++nLineNr;
151cdf0e10cSrcweir return pCurr;
152cdf0e10cSrcweir }
153cdf0e10cSrcweir else
154cdf0e10cSrcweir return 0;
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
157cdf0e10cSrcweir /*************************************************************************
158cdf0e10cSrcweir * SwTxtIter::Next()
159cdf0e10cSrcweir *************************************************************************/
160cdf0e10cSrcweir
Next()161cdf0e10cSrcweir const SwLineLayout *SwTxtIter::Next()
162cdf0e10cSrcweir {
163cdf0e10cSrcweir if(pCurr->GetNext())
164cdf0e10cSrcweir {
165cdf0e10cSrcweir pPrev = pCurr;
166cdf0e10cSrcweir bPrev = sal_True;
167cdf0e10cSrcweir nStart = nStart + pCurr->GetLen();
168cdf0e10cSrcweir nY += GetLineHeight();
169cdf0e10cSrcweir if( pCurr->GetLen() || ( nLineNr>1 && !pCurr->IsDummy() ) )
170cdf0e10cSrcweir ++nLineNr;
171cdf0e10cSrcweir return pCurr = pCurr->GetNext();
172cdf0e10cSrcweir }
173cdf0e10cSrcweir else
174cdf0e10cSrcweir return 0;
175cdf0e10cSrcweir }
176cdf0e10cSrcweir
177cdf0e10cSrcweir /*************************************************************************
178cdf0e10cSrcweir * SwTxtIter::NextLine()
179cdf0e10cSrcweir *************************************************************************/
180cdf0e10cSrcweir
NextLine()181cdf0e10cSrcweir const SwLineLayout *SwTxtIter::NextLine()
182cdf0e10cSrcweir {
183cdf0e10cSrcweir const SwLineLayout *pNext = Next();
184cdf0e10cSrcweir while( pNext && pNext->IsDummy() && pNext->GetNext() )
185cdf0e10cSrcweir {
186cdf0e10cSrcweir DBG_LOOP;
187cdf0e10cSrcweir pNext = Next();
188cdf0e10cSrcweir }
189cdf0e10cSrcweir return pNext;
190cdf0e10cSrcweir }
191cdf0e10cSrcweir
192cdf0e10cSrcweir /*************************************************************************
193cdf0e10cSrcweir * SwTxtIter::GetNextLine()
194cdf0e10cSrcweir *************************************************************************/
195cdf0e10cSrcweir
GetNextLine() const196cdf0e10cSrcweir const SwLineLayout *SwTxtIter::GetNextLine() const
197cdf0e10cSrcweir {
198cdf0e10cSrcweir const SwLineLayout *pNext = pCurr->GetNext();
199cdf0e10cSrcweir while( pNext && pNext->IsDummy() && pNext->GetNext() )
200cdf0e10cSrcweir {
201cdf0e10cSrcweir DBG_LOOP;
202cdf0e10cSrcweir pNext = pNext->GetNext();
203cdf0e10cSrcweir }
204cdf0e10cSrcweir return (SwLineLayout*)pNext;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir
207cdf0e10cSrcweir /*************************************************************************
208cdf0e10cSrcweir * SwTxtIter::GetPrevLine()
209cdf0e10cSrcweir *************************************************************************/
210cdf0e10cSrcweir
GetPrevLine()211cdf0e10cSrcweir const SwLineLayout *SwTxtIter::GetPrevLine()
212cdf0e10cSrcweir {
213cdf0e10cSrcweir const SwLineLayout *pRoot = pInf->GetParaPortion();
214cdf0e10cSrcweir if( pRoot == pCurr )
215cdf0e10cSrcweir return 0;
216cdf0e10cSrcweir const SwLineLayout *pLay = pRoot;
217cdf0e10cSrcweir
218cdf0e10cSrcweir while( pLay->GetNext() != pCurr )
219cdf0e10cSrcweir pLay = pLay->GetNext();
220cdf0e10cSrcweir
221cdf0e10cSrcweir if( pLay->IsDummy() )
222cdf0e10cSrcweir {
223cdf0e10cSrcweir const SwLineLayout *pTmp = pRoot;
224cdf0e10cSrcweir pLay = pRoot->IsDummy() ? 0 : pRoot;
225cdf0e10cSrcweir while( pTmp->GetNext() != pCurr )
226cdf0e10cSrcweir {
227cdf0e10cSrcweir if( !pTmp->IsDummy() )
228cdf0e10cSrcweir pLay = pTmp;
229cdf0e10cSrcweir pTmp = pTmp->GetNext();
230cdf0e10cSrcweir }
231cdf0e10cSrcweir }
232cdf0e10cSrcweir
233cdf0e10cSrcweir // Wenn sich nichts getan hat, dann gibt es nur noch Dummys
234cdf0e10cSrcweir return (SwLineLayout*)pLay;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir
237cdf0e10cSrcweir /*************************************************************************
238cdf0e10cSrcweir * SwTxtIter::PrevLine()
239cdf0e10cSrcweir *************************************************************************/
240cdf0e10cSrcweir
PrevLine()241cdf0e10cSrcweir const SwLineLayout *SwTxtIter::PrevLine()
242cdf0e10cSrcweir {
243cdf0e10cSrcweir const SwLineLayout *pMyPrev = Prev();
244cdf0e10cSrcweir if( !pMyPrev )
245cdf0e10cSrcweir return 0;
246cdf0e10cSrcweir
247cdf0e10cSrcweir const SwLineLayout *pLast = pMyPrev;
248cdf0e10cSrcweir while( pMyPrev && pMyPrev->IsDummy() )
249cdf0e10cSrcweir {
250cdf0e10cSrcweir DBG_LOOP;
251cdf0e10cSrcweir pLast = pMyPrev;
252cdf0e10cSrcweir pMyPrev = Prev();
253cdf0e10cSrcweir }
254cdf0e10cSrcweir return (SwLineLayout*)(pMyPrev ? pMyPrev : pLast);
255cdf0e10cSrcweir }
256cdf0e10cSrcweir
257cdf0e10cSrcweir /*************************************************************************
258cdf0e10cSrcweir * SwTxtIter::Bottom()
259cdf0e10cSrcweir *************************************************************************/
260cdf0e10cSrcweir
Bottom()261cdf0e10cSrcweir void SwTxtIter::Bottom()
262cdf0e10cSrcweir {
263cdf0e10cSrcweir while( Next() )
264cdf0e10cSrcweir {
265cdf0e10cSrcweir DBG_LOOP;
266cdf0e10cSrcweir }
267cdf0e10cSrcweir }
268cdf0e10cSrcweir
269cdf0e10cSrcweir /*************************************************************************
270cdf0e10cSrcweir * SwTxtIter::CharToLine()
271cdf0e10cSrcweir *************************************************************************/
272cdf0e10cSrcweir
CharToLine(const xub_StrLen nChar)273cdf0e10cSrcweir void SwTxtIter::CharToLine(const xub_StrLen nChar)
274cdf0e10cSrcweir {
275cdf0e10cSrcweir while( nStart + pCurr->GetLen() <= nChar && Next() )
276cdf0e10cSrcweir ;
277cdf0e10cSrcweir while( nStart > nChar && Prev() )
278cdf0e10cSrcweir ;
279cdf0e10cSrcweir }
280cdf0e10cSrcweir
281cdf0e10cSrcweir /*************************************************************************
282cdf0e10cSrcweir * SwTxtIter::CharCrsrToLine()
283cdf0e10cSrcweir *************************************************************************/
284cdf0e10cSrcweir
285cdf0e10cSrcweir // 1170: beruecksichtigt Mehrdeutigkeiten:
CharCrsrToLine(const xub_StrLen nPosition)286cdf0e10cSrcweir const SwLineLayout *SwTxtCursor::CharCrsrToLine( const xub_StrLen nPosition )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir CharToLine( nPosition );
289cdf0e10cSrcweir if( nPosition != nStart )
290cdf0e10cSrcweir bRightMargin = sal_False;
291cdf0e10cSrcweir sal_Bool bPrevious = bRightMargin && pCurr->GetLen() && GetPrev() &&
292cdf0e10cSrcweir GetPrev()->GetLen();
293cdf0e10cSrcweir if( bPrevious && nPosition && CH_BREAK == GetInfo().GetChar( nPosition-1 ) )
294cdf0e10cSrcweir bPrevious = sal_False;
295cdf0e10cSrcweir return bPrevious ? PrevLine() : pCurr;
296cdf0e10cSrcweir }
297cdf0e10cSrcweir
298cdf0e10cSrcweir /*************************************************************************
299cdf0e10cSrcweir * SwTxtCrsr::AdjustBaseLine()
300cdf0e10cSrcweir *************************************************************************/
301cdf0e10cSrcweir
AdjustBaseLine(const SwLineLayout & rLine,const SwLinePortion * pPor,sal_uInt16 nPorHeight,sal_uInt16 nPorAscent,const sal_Bool bAutoToCentered) const302cdf0e10cSrcweir sal_uInt16 SwTxtCursor::AdjustBaseLine( const SwLineLayout& rLine,
303cdf0e10cSrcweir const SwLinePortion* pPor,
304cdf0e10cSrcweir sal_uInt16 nPorHeight, sal_uInt16 nPorAscent,
305cdf0e10cSrcweir const sal_Bool bAutoToCentered ) const
306cdf0e10cSrcweir {
307cdf0e10cSrcweir if ( pPor )
308cdf0e10cSrcweir {
309cdf0e10cSrcweir nPorHeight = pPor->Height();
310cdf0e10cSrcweir nPorAscent = pPor->GetAscent();
311cdf0e10cSrcweir }
312cdf0e10cSrcweir
313cdf0e10cSrcweir sal_uInt16 nOfst = rLine.GetRealHeight() - rLine.Height();
314cdf0e10cSrcweir
315cdf0e10cSrcweir GETGRID( pFrm->FindPageFrm() )
316cdf0e10cSrcweir const sal_Bool bHasGrid = pGrid && GetInfo().SnapToGrid();
317cdf0e10cSrcweir
318cdf0e10cSrcweir if ( bHasGrid )
319cdf0e10cSrcweir {
320cdf0e10cSrcweir const sal_uInt16 nRubyHeight = pGrid->GetRubyHeight();
321cdf0e10cSrcweir const sal_Bool bRubyTop = ! pGrid->GetRubyTextBelow();
322cdf0e10cSrcweir
323cdf0e10cSrcweir if ( GetInfo().IsMulti() )
324cdf0e10cSrcweir // we are inside the GetCharRect recursion for multi portions
325cdf0e10cSrcweir // we center the portion in its surrounding line
326cdf0e10cSrcweir nOfst = ( pCurr->Height() - nPorHeight ) / 2 + nPorAscent;
327cdf0e10cSrcweir else
328cdf0e10cSrcweir {
329cdf0e10cSrcweir // We have to take care for ruby portions.
330cdf0e10cSrcweir // The ruby portion is NOT centered
331cdf0e10cSrcweir nOfst = nOfst + nPorAscent;
332cdf0e10cSrcweir
333cdf0e10cSrcweir if ( ! pPor || ! pPor->IsMultiPortion() ||
334cdf0e10cSrcweir ! ((SwMultiPortion*)pPor)->IsRuby() )
335cdf0e10cSrcweir {
336cdf0e10cSrcweir // Portions which are bigger than on grid distance are
337cdf0e10cSrcweir // centered inside the whole line.
338cdf0e10cSrcweir
339cdf0e10cSrcweir //for text refactor
340cdf0e10cSrcweir const sal_uInt16 nLineNetto = rLine.Height() - nRubyHeight;
341cdf0e10cSrcweir //const sal_uInt16 nLineNetto = ( nPorHeight > nGridWidth ) ?
342cdf0e10cSrcweir // rLine.Height() - nRubyHeight :
343cdf0e10cSrcweir // nGridWidth;
344cdf0e10cSrcweir nOfst += ( nLineNetto - nPorHeight ) / 2;
345cdf0e10cSrcweir if ( bRubyTop )
346cdf0e10cSrcweir nOfst = nOfst + nRubyHeight;
347cdf0e10cSrcweir }
348cdf0e10cSrcweir }
349cdf0e10cSrcweir }
350cdf0e10cSrcweir else
351cdf0e10cSrcweir {
352cdf0e10cSrcweir switch ( GetLineInfo().GetVertAlign() ) {
353cdf0e10cSrcweir case SvxParaVertAlignItem::TOP :
354cdf0e10cSrcweir nOfst = nOfst + nPorAscent;
355cdf0e10cSrcweir break;
356cdf0e10cSrcweir case SvxParaVertAlignItem::CENTER :
357cdf0e10cSrcweir ASSERT( rLine.Height() >= nPorHeight, "Portion height > Line height");
358cdf0e10cSrcweir nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent;
359cdf0e10cSrcweir break;
360cdf0e10cSrcweir case SvxParaVertAlignItem::BOTTOM :
361cdf0e10cSrcweir nOfst += rLine.Height() - nPorHeight + nPorAscent;
362cdf0e10cSrcweir break;
363cdf0e10cSrcweir case SvxParaVertAlignItem::AUTOMATIC :
364cdf0e10cSrcweir if ( bAutoToCentered || GetInfo().GetTxtFrm()->IsVertical() )
365cdf0e10cSrcweir {
366cdf0e10cSrcweir //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
367cdf0e10cSrcweir if( GetInfo().GetTxtFrm()->IsVertLR() )
368cdf0e10cSrcweir nOfst += rLine.Height() - ( rLine.Height() - nPorHeight ) / 2 - nPorAscent;
369cdf0e10cSrcweir else
370cdf0e10cSrcweir nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent;
371cdf0e10cSrcweir break;
372cdf0e10cSrcweir }
373cdf0e10cSrcweir case SvxParaVertAlignItem::BASELINE :
374cdf0e10cSrcweir // base line
375cdf0e10cSrcweir nOfst = nOfst + rLine.GetAscent();
376cdf0e10cSrcweir break;
377cdf0e10cSrcweir }
378cdf0e10cSrcweir }
379cdf0e10cSrcweir
380cdf0e10cSrcweir return nOfst;
381cdf0e10cSrcweir }
382cdf0e10cSrcweir
383cdf0e10cSrcweir /*************************************************************************
384cdf0e10cSrcweir * SwTxtIter::TwipsToLine()
385cdf0e10cSrcweir *************************************************************************/
386cdf0e10cSrcweir
TwipsToLine(const SwTwips y)387cdf0e10cSrcweir const SwLineLayout *SwTxtIter::TwipsToLine( const SwTwips y)
388cdf0e10cSrcweir {
389cdf0e10cSrcweir while( nY + GetLineHeight() <= y && Next() )
390cdf0e10cSrcweir ;
391cdf0e10cSrcweir while( nY > y && Prev() )
392cdf0e10cSrcweir ;
393cdf0e10cSrcweir return pCurr;
394cdf0e10cSrcweir }
395cdf0e10cSrcweir
396cdf0e10cSrcweir //
397cdf0e10cSrcweir // Local helper function to check, if pCurr needs a field rest portion:
398cdf0e10cSrcweir //
lcl_NeedsFieldRest(const SwLineLayout * pCurr)399cdf0e10cSrcweir sal_Bool lcl_NeedsFieldRest( const SwLineLayout* pCurr )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir const SwLinePortion *pPor = pCurr->GetPortion();
402cdf0e10cSrcweir sal_Bool bRet = sal_False;
403cdf0e10cSrcweir while( pPor && !bRet )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir bRet = pPor->InFldGrp() && ((SwFldPortion*)pPor)->HasFollow();
406cdf0e10cSrcweir if( !pPor->GetPortion() || !pPor->GetPortion()->InFldGrp() )
407cdf0e10cSrcweir break;
408cdf0e10cSrcweir pPor = pPor->GetPortion();
409cdf0e10cSrcweir }
410cdf0e10cSrcweir return bRet;
411cdf0e10cSrcweir }
412cdf0e10cSrcweir
413cdf0e10cSrcweir /*************************************************************************
414cdf0e10cSrcweir * SwTxtIter::TruncLines()
415cdf0e10cSrcweir *************************************************************************/
416cdf0e10cSrcweir
TruncLines(sal_Bool bNoteFollow)417cdf0e10cSrcweir void SwTxtIter::TruncLines( sal_Bool bNoteFollow )
418cdf0e10cSrcweir {
419cdf0e10cSrcweir SwLineLayout *pDel = pCurr->GetNext();
420cdf0e10cSrcweir const xub_StrLen nEnd = nStart + pCurr->GetLen();
421cdf0e10cSrcweir
422cdf0e10cSrcweir if( pDel )
423cdf0e10cSrcweir {
424cdf0e10cSrcweir pCurr->SetNext( 0 );
425cdf0e10cSrcweir if( GetHints() && bNoteFollow )
426cdf0e10cSrcweir {
427cdf0e10cSrcweir GetInfo().GetParaPortion()->SetFollowField( pDel->IsRest() ||
428cdf0e10cSrcweir lcl_NeedsFieldRest( pCurr ) );
429cdf0e10cSrcweir
430cdf0e10cSrcweir // bug 88534: wrong positioning of flys
431cdf0e10cSrcweir SwTxtFrm* pFollow = GetTxtFrm()->GetFollow();
432cdf0e10cSrcweir if ( pFollow && ! pFollow->IsLocked() &&
433cdf0e10cSrcweir nEnd == pFollow->GetOfst() )
434cdf0e10cSrcweir {
435cdf0e10cSrcweir xub_StrLen nRangeEnd = nEnd;
436cdf0e10cSrcweir SwLineLayout* pLine = pDel;
437cdf0e10cSrcweir
438cdf0e10cSrcweir // determine range to be searched for flys anchored as characters
439cdf0e10cSrcweir while ( pLine )
440cdf0e10cSrcweir {
441cdf0e10cSrcweir nRangeEnd = nRangeEnd + pLine->GetLen();
442cdf0e10cSrcweir pLine = pLine->GetNext();
443cdf0e10cSrcweir }
444cdf0e10cSrcweir
445cdf0e10cSrcweir SwpHints* pTmpHints = GetTxtFrm()->GetTxtNode()->GetpSwpHints();
446cdf0e10cSrcweir
447cdf0e10cSrcweir // examine hints in range nEnd - (nEnd + nRangeChar)
448cdf0e10cSrcweir for( sal_uInt16 i = 0; i < pTmpHints->Count(); i++ )
449cdf0e10cSrcweir {
450cdf0e10cSrcweir const SwTxtAttr* pHt = pTmpHints->GetTextHint( i );
451cdf0e10cSrcweir if( RES_TXTATR_FLYCNT == pHt->Which() )
452cdf0e10cSrcweir {
453cdf0e10cSrcweir // check, if hint is in our range
454cdf0e10cSrcweir const sal_uInt16 nTmpPos = *pHt->GetStart();
455cdf0e10cSrcweir if ( nEnd <= nTmpPos && nTmpPos < nRangeEnd )
456cdf0e10cSrcweir pFollow->_InvalidateRange(
457cdf0e10cSrcweir SwCharRange( nTmpPos, nTmpPos ), 0 );
458cdf0e10cSrcweir }
459cdf0e10cSrcweir }
460cdf0e10cSrcweir }
461cdf0e10cSrcweir }
462cdf0e10cSrcweir delete pDel;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir if( pCurr->IsDummy() &&
465cdf0e10cSrcweir !pCurr->GetLen() &&
466cdf0e10cSrcweir nStart < GetTxtFrm()->GetTxt().Len() )
467cdf0e10cSrcweir pCurr->SetRealHeight( 1 );
468cdf0e10cSrcweir if( GetHints() )
469cdf0e10cSrcweir pFrm->RemoveFtn( nEnd );
470cdf0e10cSrcweir }
471cdf0e10cSrcweir
472cdf0e10cSrcweir /*************************************************************************
473cdf0e10cSrcweir * SwTxtIter::CntHyphens()
474cdf0e10cSrcweir *************************************************************************/
475cdf0e10cSrcweir
CntHyphens(sal_uInt8 & nEndCnt,sal_uInt8 & nMidCnt) const476cdf0e10cSrcweir void SwTxtIter::CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const
477cdf0e10cSrcweir {
478cdf0e10cSrcweir nEndCnt = 0;
479cdf0e10cSrcweir nMidCnt = 0;
480cdf0e10cSrcweir if ( bPrev && pPrev && !pPrev->IsEndHyph() && !pPrev->IsMidHyph() )
481cdf0e10cSrcweir return;
482cdf0e10cSrcweir SwLineLayout *pLay = pInf->GetParaPortion();
483cdf0e10cSrcweir if( pCurr == pLay )
484cdf0e10cSrcweir return;
485cdf0e10cSrcweir while( pLay != pCurr )
486cdf0e10cSrcweir {
487cdf0e10cSrcweir DBG_LOOP;
488cdf0e10cSrcweir if ( pLay->IsEndHyph() )
489cdf0e10cSrcweir nEndCnt++;
490cdf0e10cSrcweir else
491cdf0e10cSrcweir nEndCnt = 0;
492cdf0e10cSrcweir if ( pLay->IsMidHyph() )
493cdf0e10cSrcweir nMidCnt++;
494cdf0e10cSrcweir else
495cdf0e10cSrcweir nMidCnt = 0;
496cdf0e10cSrcweir pLay = pLay->GetNext();
497cdf0e10cSrcweir }
498cdf0e10cSrcweir }
499cdf0e10cSrcweir
500cdf0e10cSrcweir /*************************************************************************
501cdf0e10cSrcweir * SwHookOut
502cdf0e10cSrcweir *
503cdf0e10cSrcweir * Change current output device to formatting device, this has to be done before
504cdf0e10cSrcweir * formatting.
505cdf0e10cSrcweir *************************************************************************/
506cdf0e10cSrcweir
SwHookOut(SwTxtSizeInfo & rInfo)507cdf0e10cSrcweir SwHookOut::SwHookOut( SwTxtSizeInfo& rInfo ) :
508cdf0e10cSrcweir pInf( &rInfo ),
509cdf0e10cSrcweir pOut( rInfo.GetOut() ),
510cdf0e10cSrcweir bOnWin( rInfo.OnWin() )
511cdf0e10cSrcweir {
512cdf0e10cSrcweir ASSERT( rInfo.GetRefDev(), "No reference device for text formatting" )
513cdf0e10cSrcweir
514cdf0e10cSrcweir // set new values
515cdf0e10cSrcweir rInfo.SetOut( rInfo.GetRefDev() );
516cdf0e10cSrcweir rInfo.SetOnWin( sal_False );
517cdf0e10cSrcweir }
518cdf0e10cSrcweir
~SwHookOut()519cdf0e10cSrcweir SwHookOut::~SwHookOut()
520cdf0e10cSrcweir {
521cdf0e10cSrcweir pInf->SetOut( pOut );
522cdf0e10cSrcweir pInf->SetOnWin( bOnWin );
523cdf0e10cSrcweir }
524