xref: /AOO41X/main/sw/source/core/text/itrtxt.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
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