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
10efeef26fSAndrew Rist *
11efeef26fSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12efeef26fSAndrew Rist *
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.
19efeef26fSAndrew Rist *
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 #include <editeng/charscaleitem.hxx>
30cdf0e10cSrcweir #include <txtatr.hxx>
31cdf0e10cSrcweir #include <sfx2/printer.hxx>
32cdf0e10cSrcweir #include <svx/svdobj.hxx>
33cdf0e10cSrcweir #include <vcl/window.hxx>
34cdf0e10cSrcweir #include <vcl/svapp.hxx>
35cdf0e10cSrcweir #include <fmtanchr.hxx>
36cdf0e10cSrcweir #include <fmtfsize.hxx>
37cdf0e10cSrcweir #include <fmtornt.hxx>
38cdf0e10cSrcweir #include <fmtflcnt.hxx>
39cdf0e10cSrcweir #include <fmtcntnt.hxx>
40cdf0e10cSrcweir #include <fmtftn.hxx>
41cdf0e10cSrcweir #include <frmatr.hxx>
42cdf0e10cSrcweir #include <frmfmt.hxx>
43cdf0e10cSrcweir #include <fmtfld.hxx>
44cdf0e10cSrcweir #include <doc.hxx>
45cdf0e10cSrcweir #include <viewsh.hxx> // ViewShell
46cdf0e10cSrcweir #include <rootfrm.hxx>
47cdf0e10cSrcweir #include <docary.hxx>
48cdf0e10cSrcweir #include <ndtxt.hxx>
49cdf0e10cSrcweir #include <dcontact.hxx>
50cdf0e10cSrcweir #include <fldbas.hxx> // SwField
51cdf0e10cSrcweir #include <pam.hxx> // SwPosition (lcl_MinMaxNode)
52cdf0e10cSrcweir #include <itratr.hxx>
53cdf0e10cSrcweir #include <htmltbl.hxx>
54cdf0e10cSrcweir #include <swtable.hxx>
55cdf0e10cSrcweir #include <redlnitr.hxx>
56cdf0e10cSrcweir #include <fmtsrnd.hxx>
57cdf0e10cSrcweir #include <itrtxt.hxx>
58cdf0e10cSrcweir #include <breakit.hxx>
59cdf0e10cSrcweir #include <com/sun/star/i18n/WordType.hpp>
60cdf0e10cSrcweir #include <com/sun/star/i18n/ScriptType.hdl>
61cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
62cdf0e10cSrcweir #include <switerator.hxx>
63cdf0e10cSrcweir
64cdf0e10cSrcweir using namespace ::com::sun::star::i18n;
65cdf0e10cSrcweir using namespace ::com::sun::star;
66cdf0e10cSrcweir
67cdf0e10cSrcweir /*************************************************************************
68cdf0e10cSrcweir * SwAttrIter::Chg()
69cdf0e10cSrcweir *************************************************************************/
70cdf0e10cSrcweir
Chg(SwTxtAttr * pHt)71cdf0e10cSrcweir void SwAttrIter::Chg( SwTxtAttr *pHt )
72cdf0e10cSrcweir {
73cdf0e10cSrcweir ASSERT( pHt && pFnt, "No attribute of font available for change");
74cdf0e10cSrcweir if( pRedln && pRedln->IsOn() )
75cdf0e10cSrcweir pRedln->ChangeTxtAttr( pFnt, *pHt, sal_True );
76cdf0e10cSrcweir else
77cdf0e10cSrcweir aAttrHandler.PushAndChg( *pHt, *pFnt );
78cdf0e10cSrcweir nChgCnt++;
79cdf0e10cSrcweir }
80cdf0e10cSrcweir
81cdf0e10cSrcweir /*************************************************************************
82cdf0e10cSrcweir * SwAttrIter::Rst()
83cdf0e10cSrcweir *************************************************************************/
84cdf0e10cSrcweir
Rst(SwTxtAttr * pHt)85cdf0e10cSrcweir void SwAttrIter::Rst( SwTxtAttr *pHt )
86cdf0e10cSrcweir {
87cdf0e10cSrcweir ASSERT( pHt && pFnt, "No attribute of font available for reset");
88cdf0e10cSrcweir // get top from stack after removing pHt
89cdf0e10cSrcweir if( pRedln && pRedln->IsOn() )
90cdf0e10cSrcweir pRedln->ChangeTxtAttr( pFnt, *pHt, sal_False );
91cdf0e10cSrcweir else
92cdf0e10cSrcweir aAttrHandler.PopAndChg( *pHt, *pFnt );
93cdf0e10cSrcweir nChgCnt--;
94cdf0e10cSrcweir }
95cdf0e10cSrcweir
96cdf0e10cSrcweir /*************************************************************************
97cdf0e10cSrcweir * virtual SwAttrIter::~SwAttrIter()
98cdf0e10cSrcweir *************************************************************************/
99cdf0e10cSrcweir
~SwAttrIter()100cdf0e10cSrcweir SwAttrIter::~SwAttrIter()
101cdf0e10cSrcweir {
102cdf0e10cSrcweir delete pRedln;
103cdf0e10cSrcweir delete pFnt;
104cdf0e10cSrcweir }
105cdf0e10cSrcweir
106cdf0e10cSrcweir /*************************************************************************
107cdf0e10cSrcweir * SwAttrIter::GetAttr()
108cdf0e10cSrcweir *
109cdf0e10cSrcweir * Liefert fuer eine Position das Attribut, wenn das Attribut genau auf
110cdf0e10cSrcweir * der Position nPos liegt und kein EndIndex besitzt.
111cdf0e10cSrcweir * GetAttr() wird fuer Attribute benoetigt, die die Formatierung beeinflussen
112cdf0e10cSrcweir * sollen, ohne dabei den Inhalt des Strings zu veraendern. Solche "entarteten"
113cdf0e10cSrcweir * Attribute sind z.B. Felder (die expandierten Text bereit halten) und
114cdf0e10cSrcweir * zeilengebundene Frames. Um Mehrdeutigkeiten zwischen verschiedenen
115cdf0e10cSrcweir * solcher Attribute zu vermeiden, werden beim Anlegen eines Attributs
116cdf0e10cSrcweir * an der Startposition ein Sonderzeichen in den String einfuegt.
117cdf0e10cSrcweir * Der Formatierer stoesst auf das Sonderzeichen und holt sich per
118cdf0e10cSrcweir * GetAttr() das entartete Attribut.
119cdf0e10cSrcweir *************************************************************************/
120cdf0e10cSrcweir
GetAttr(const xub_StrLen nPosition) const121cdf0e10cSrcweir SwTxtAttr *SwAttrIter::GetAttr( const xub_StrLen nPosition ) const
122cdf0e10cSrcweir {
123cdf0e10cSrcweir return (m_pTxtNode) ? m_pTxtNode->GetTxtAttrForCharAt(nPosition) : 0;
124cdf0e10cSrcweir }
125cdf0e10cSrcweir
126cdf0e10cSrcweir /*************************************************************************
127cdf0e10cSrcweir * SwAttrIter::SeekAndChg()
128cdf0e10cSrcweir *************************************************************************/
129cdf0e10cSrcweir
SeekAndChgAttrIter(const xub_StrLen nNewPos,OutputDevice * pOut)130cdf0e10cSrcweir sal_Bool SwAttrIter::SeekAndChgAttrIter( const xub_StrLen nNewPos, OutputDevice* pOut )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir sal_Bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos );
133cdf0e10cSrcweir if ( pLastOut != pOut )
134cdf0e10cSrcweir {
135cdf0e10cSrcweir pLastOut = pOut;
136cdf0e10cSrcweir pFnt->SetFntChg( sal_True );
137cdf0e10cSrcweir bChg = sal_True;
138cdf0e10cSrcweir }
139cdf0e10cSrcweir if( bChg )
140cdf0e10cSrcweir {
141cdf0e10cSrcweir // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
142cdf0e10cSrcweir // des gewuenschten Fonts ...
143cdf0e10cSrcweir if ( !nChgCnt && !nPropFont )
144cdf0e10cSrcweir pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
145cdf0e10cSrcweir aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
146cdf0e10cSrcweir pFnt->ChgPhysFnt( pShell, *pOut );
147cdf0e10cSrcweir }
148cdf0e10cSrcweir return bChg;
149cdf0e10cSrcweir }
150cdf0e10cSrcweir
IsSymbol(const xub_StrLen nNewPos)151cdf0e10cSrcweir sal_Bool SwAttrIter::IsSymbol( const xub_StrLen nNewPos )
152cdf0e10cSrcweir {
153cdf0e10cSrcweir Seek( nNewPos );
154cdf0e10cSrcweir if ( !nChgCnt && !nPropFont )
155cdf0e10cSrcweir pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
156cdf0e10cSrcweir aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
157cdf0e10cSrcweir return pFnt->IsSymbol( pShell );
158cdf0e10cSrcweir }
159cdf0e10cSrcweir
160cdf0e10cSrcweir /*************************************************************************
161cdf0e10cSrcweir * SwAttrIter::SeekStartAndChg()
162cdf0e10cSrcweir *************************************************************************/
163cdf0e10cSrcweir
SeekStartAndChgAttrIter(OutputDevice * pOut,const sal_Bool bParaFont)164cdf0e10cSrcweir sal_Bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const sal_Bool bParaFont )
165cdf0e10cSrcweir {
166cdf0e10cSrcweir if ( pRedln && pRedln->ExtOn() )
167cdf0e10cSrcweir pRedln->LeaveExtend( *pFnt, 0 );
168cdf0e10cSrcweir
169cdf0e10cSrcweir // reset font to its original state
170cdf0e10cSrcweir aAttrHandler.Reset();
171cdf0e10cSrcweir aAttrHandler.ResetFont( *pFnt );
172cdf0e10cSrcweir
173cdf0e10cSrcweir nStartIndex = nEndIndex = nPos = nChgCnt = 0;
174cdf0e10cSrcweir if( nPropFont )
175cdf0e10cSrcweir pFnt->SetProportion( nPropFont );
176cdf0e10cSrcweir if( pRedln )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir pRedln->Clear( pFnt );
179cdf0e10cSrcweir if( !bParaFont )
180cdf0e10cSrcweir nChgCnt = nChgCnt + pRedln->Seek( *pFnt, 0, STRING_LEN );
181cdf0e10cSrcweir else
182cdf0e10cSrcweir pRedln->Reset();
183cdf0e10cSrcweir }
184cdf0e10cSrcweir
185cdf0e10cSrcweir if ( pHints && !bParaFont )
186cdf0e10cSrcweir {
187cdf0e10cSrcweir SwTxtAttr *pTxtAttr;
188cdf0e10cSrcweir // Solange wir noch nicht am Ende des StartArrays angekommen sind &&
189cdf0e10cSrcweir // das TextAttribut an Position 0 beginnt ...
190cdf0e10cSrcweir while ( ( nStartIndex < pHints->GetStartCount() ) &&
191cdf0e10cSrcweir !(*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()) )
192cdf0e10cSrcweir {
193cdf0e10cSrcweir // oeffne die TextAttribute
194cdf0e10cSrcweir Chg( pTxtAttr );
195cdf0e10cSrcweir nStartIndex++;
196cdf0e10cSrcweir }
197cdf0e10cSrcweir }
198cdf0e10cSrcweir
199cdf0e10cSrcweir sal_Bool bChg = pFnt->IsFntChg();
200cdf0e10cSrcweir if ( pLastOut != pOut )
201cdf0e10cSrcweir {
202cdf0e10cSrcweir pLastOut = pOut;
203cdf0e10cSrcweir pFnt->SetFntChg( sal_True );
204cdf0e10cSrcweir bChg = sal_True;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir if( bChg )
207cdf0e10cSrcweir {
208cdf0e10cSrcweir // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
209cdf0e10cSrcweir // des gewuenschten Fonts ...
210cdf0e10cSrcweir if ( !nChgCnt && !nPropFont )
211cdf0e10cSrcweir pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
212cdf0e10cSrcweir aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
213cdf0e10cSrcweir pFnt->ChgPhysFnt( pShell, *pOut );
214cdf0e10cSrcweir }
215cdf0e10cSrcweir return bChg;
216cdf0e10cSrcweir }
217cdf0e10cSrcweir
218cdf0e10cSrcweir /*************************************************************************
219cdf0e10cSrcweir * SwAttrIter::SeekFwd()
220cdf0e10cSrcweir *************************************************************************/
221cdf0e10cSrcweir
222cdf0e10cSrcweir // AMA: Neuer AttrIter Nov 94
223cdf0e10cSrcweir
SeekFwd(const xub_StrLen nNewPos)224cdf0e10cSrcweir void SwAttrIter::SeekFwd( const xub_StrLen nNewPos )
225cdf0e10cSrcweir {
226cdf0e10cSrcweir SwTxtAttr *pTxtAttr;
227cdf0e10cSrcweir
228cdf0e10cSrcweir if ( nStartIndex ) // wenn ueberhaupt schon Attribute geoeffnet wurden...
229cdf0e10cSrcweir {
230cdf0e10cSrcweir // Schliesse Attr, die z. Z. geoeffnet sind, vor nNewPos+1 aber enden.
231cdf0e10cSrcweir
232cdf0e10cSrcweir // Solange wir noch nicht am Ende des EndArrays angekommen sind &&
233cdf0e10cSrcweir // das TextAttribut vor oder an der neuen Position endet ...
234cdf0e10cSrcweir while ( ( nEndIndex < pHints->GetEndCount() ) &&
235cdf0e10cSrcweir (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
236cdf0e10cSrcweir {
237cdf0e10cSrcweir // schliesse die TextAttribute, deren StartPos vor
238cdf0e10cSrcweir // oder an der alten nPos lag, die z.Z. geoeffnet sind.
239cdf0e10cSrcweir if (*pTxtAttr->GetStart() <= nPos) Rst( pTxtAttr );
240cdf0e10cSrcweir nEndIndex++;
241cdf0e10cSrcweir }
242cdf0e10cSrcweir }
243cdf0e10cSrcweir else // ueberlies die nicht geoeffneten Enden
244cdf0e10cSrcweir {
245cdf0e10cSrcweir while ( ( nEndIndex < pHints->GetEndCount() ) &&
246cdf0e10cSrcweir (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
247cdf0e10cSrcweir {
248cdf0e10cSrcweir nEndIndex++;
249cdf0e10cSrcweir }
250cdf0e10cSrcweir }
251cdf0e10cSrcweir // Solange wir noch nicht am Ende des StartArrays angekommen sind &&
252cdf0e10cSrcweir // das TextAttribut vor oder an der neuen Position beginnt ...
253cdf0e10cSrcweir while ( ( nStartIndex < pHints->GetStartCount() ) &&
254cdf0e10cSrcweir (*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()<=nNewPos))
255cdf0e10cSrcweir {
256cdf0e10cSrcweir // oeffne die TextAttribute, deren Ende hinter der neuen Position liegt
257cdf0e10cSrcweir if ( *pTxtAttr->GetAnyEnd() > nNewPos ) Chg( pTxtAttr );
258cdf0e10cSrcweir nStartIndex++;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir
261cdf0e10cSrcweir }
262cdf0e10cSrcweir
263cdf0e10cSrcweir /*************************************************************************
264cdf0e10cSrcweir * SwAttrIter::Seek()
265cdf0e10cSrcweir *************************************************************************/
266cdf0e10cSrcweir
Seek(const xub_StrLen nNewPos)267cdf0e10cSrcweir sal_Bool SwAttrIter::Seek( const xub_StrLen nNewPos )
268cdf0e10cSrcweir {
269cdf0e10cSrcweir if ( pRedln && pRedln->ExtOn() )
270cdf0e10cSrcweir pRedln->LeaveExtend( *pFnt, nNewPos );
271cdf0e10cSrcweir
272cdf0e10cSrcweir if( pHints )
273cdf0e10cSrcweir {
274cdf0e10cSrcweir if( !nNewPos || nNewPos < nPos )
275cdf0e10cSrcweir {
276cdf0e10cSrcweir if( pRedln )
277cdf0e10cSrcweir pRedln->Clear( NULL );
278cdf0e10cSrcweir
279cdf0e10cSrcweir // reset font to its original state
280cdf0e10cSrcweir aAttrHandler.Reset();
281cdf0e10cSrcweir aAttrHandler.ResetFont( *pFnt );
282cdf0e10cSrcweir
283cdf0e10cSrcweir if( nPropFont )
284cdf0e10cSrcweir pFnt->SetProportion( nPropFont );
285cdf0e10cSrcweir nStartIndex = nEndIndex = nPos = 0;
286cdf0e10cSrcweir nChgCnt = 0;
287cdf0e10cSrcweir
288cdf0e10cSrcweir // Achtung!
289cdf0e10cSrcweir // resetting the font here makes it necessary to apply any
290cdf0e10cSrcweir // changes for extended input directly to the font
291cdf0e10cSrcweir if ( pRedln && pRedln->ExtOn() )
292cdf0e10cSrcweir {
293cdf0e10cSrcweir pRedln->UpdateExtFont( *pFnt );
294cdf0e10cSrcweir ++nChgCnt;
295cdf0e10cSrcweir }
296cdf0e10cSrcweir }
297cdf0e10cSrcweir SeekFwd( nNewPos );
298cdf0e10cSrcweir }
299cdf0e10cSrcweir
300cdf0e10cSrcweir pFnt->SetActual( SwScriptInfo::WhichFont( nNewPos, 0, pScriptInfo ) );
301cdf0e10cSrcweir
302cdf0e10cSrcweir if( pRedln )
303cdf0e10cSrcweir nChgCnt = nChgCnt + pRedln->Seek( *pFnt, nNewPos, nPos );
304cdf0e10cSrcweir nPos = nNewPos;
305cdf0e10cSrcweir
306cdf0e10cSrcweir if( nPropFont )
307cdf0e10cSrcweir pFnt->SetProportion( nPropFont );
308cdf0e10cSrcweir
309cdf0e10cSrcweir return pFnt->IsFntChg();
310cdf0e10cSrcweir }
311cdf0e10cSrcweir
312cdf0e10cSrcweir /*************************************************************************
313cdf0e10cSrcweir * SwAttrIter::GetNextAttr()
314cdf0e10cSrcweir *************************************************************************/
315cdf0e10cSrcweir
GetNextAttr() const316cdf0e10cSrcweir xub_StrLen SwAttrIter::GetNextAttr( ) const
317cdf0e10cSrcweir {
318cdf0e10cSrcweir xub_StrLen nNext = STRING_LEN;
319cdf0e10cSrcweir if( pHints )
320cdf0e10cSrcweir {
321cdf0e10cSrcweir if (pHints->GetStartCount() > nStartIndex) // Gibt es noch Starts?
322cdf0e10cSrcweir nNext = (*pHints->GetStart(nStartIndex)->GetStart());
323cdf0e10cSrcweir if (pHints->GetEndCount() > nEndIndex) // Gibt es noch Enden?
324cdf0e10cSrcweir {
325cdf0e10cSrcweir xub_StrLen nNextEnd = (*pHints->GetEnd(nEndIndex)->GetAnyEnd());
326cdf0e10cSrcweir if ( nNextEnd<nNext ) nNext = nNextEnd; // Wer ist naeher?
327cdf0e10cSrcweir }
328cdf0e10cSrcweir }
329cdf0e10cSrcweir if (m_pTxtNode!=NULL) {
330cdf0e10cSrcweir //TODO maybe use hints like FieldHints for this instead of looking at the text...
331cdf0e10cSrcweir int l=(nNext<m_pTxtNode->Len()?nNext:m_pTxtNode->Len());
332cdf0e10cSrcweir sal_uInt16 p=nPos;
333cdf0e10cSrcweir const sal_Unicode *txt=m_pTxtNode->GetTxt().GetBuffer();
334cdf0e10cSrcweir while(p<l && txt[p]!=CH_TXT_ATR_FIELDSTART && txt[p]!=CH_TXT_ATR_FIELDEND && txt[p]!=CH_TXT_ATR_FORMELEMENT) p++;
335cdf0e10cSrcweir if ((p<l && p>nPos) || nNext<=p)
336cdf0e10cSrcweir nNext=p;
337cdf0e10cSrcweir else
338cdf0e10cSrcweir nNext=p+1;
339cdf0e10cSrcweir }
340cdf0e10cSrcweir if( pRedln )
341cdf0e10cSrcweir return pRedln->GetNextRedln( nNext );
342cdf0e10cSrcweir return nNext;
343cdf0e10cSrcweir }
344cdf0e10cSrcweir
345cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
346cdf0e10cSrcweir /*************************************************************************
347cdf0e10cSrcweir * SwAttrIter::Dump()
348cdf0e10cSrcweir *************************************************************************/
349cdf0e10cSrcweir
Dump(SvStream &) const350cdf0e10cSrcweir void SwAttrIter::Dump( SvStream &/*rOS*/ ) const
351cdf0e10cSrcweir {
352cdf0e10cSrcweir // Noch nicht an den neuen Attributiterator angepasst ...
353cdf0e10cSrcweir }
354cdf0e10cSrcweir
355cdf0e10cSrcweir #endif
356cdf0e10cSrcweir
357cdf0e10cSrcweir class SwMinMaxArgs
358cdf0e10cSrcweir {
359cdf0e10cSrcweir public:
360cdf0e10cSrcweir OutputDevice* pOut;
361cdf0e10cSrcweir ViewShell* pSh;
362cdf0e10cSrcweir sal_uLong &rMin;
363cdf0e10cSrcweir sal_uLong &rMax;
364cdf0e10cSrcweir sal_uLong &rAbsMin;
365cdf0e10cSrcweir long nRowWidth;
366cdf0e10cSrcweir long nWordWidth;
367cdf0e10cSrcweir long nWordAdd;
368cdf0e10cSrcweir xub_StrLen nNoLineBreak;
SwMinMaxArgs(OutputDevice * pOutI,ViewShell * pShI,sal_uLong & rMinI,sal_uLong & rMaxI,sal_uLong & rAbsI)369cdf0e10cSrcweir SwMinMaxArgs( OutputDevice* pOutI, ViewShell* pShI, sal_uLong& rMinI, sal_uLong &rMaxI, sal_uLong &rAbsI )
370cdf0e10cSrcweir : pOut( pOutI ), pSh( pShI ), rMin( rMinI ), rMax( rMaxI ), rAbsMin( rAbsI )
371cdf0e10cSrcweir { nRowWidth = nWordWidth = nWordAdd = 0; nNoLineBreak = STRING_LEN; }
Minimum(long nNew)372cdf0e10cSrcweir void Minimum( long nNew ) { if( (long)rMin < nNew ) rMin = nNew; }
NewWord()373cdf0e10cSrcweir void NewWord() { nWordAdd = nWordWidth = 0; }
374cdf0e10cSrcweir };
375cdf0e10cSrcweir
lcl_MinMaxString(SwMinMaxArgs & rArg,SwFont * pFnt,const XubString & rTxt,xub_StrLen nIdx,xub_StrLen nEnd)376cdf0e10cSrcweir sal_Bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const XubString &rTxt,
377cdf0e10cSrcweir xub_StrLen nIdx, xub_StrLen nEnd )
378cdf0e10cSrcweir {
379cdf0e10cSrcweir sal_Bool bRet = sal_False;
380cdf0e10cSrcweir while( nIdx < nEnd )
381cdf0e10cSrcweir {
382cdf0e10cSrcweir xub_StrLen nStop = nIdx;
383cdf0e10cSrcweir sal_Bool bClear;
384cdf0e10cSrcweir LanguageType eLang = pFnt->GetLanguage();
385cdf0e10cSrcweir if( pBreakIt->GetBreakIter().is() )
386cdf0e10cSrcweir {
387cdf0e10cSrcweir bClear = CH_BLANK == rTxt.GetChar( nStop );
388cdf0e10cSrcweir Boundary aBndry( pBreakIt->GetBreakIter()->getWordBoundary( rTxt, nIdx,
389cdf0e10cSrcweir pBreakIt->GetLocale( eLang ),
390cdf0e10cSrcweir WordType::DICTIONARY_WORD, sal_True ) );
391cdf0e10cSrcweir nStop = (xub_StrLen)aBndry.endPos;
392cdf0e10cSrcweir if( nIdx <= aBndry.startPos && nIdx && nIdx-1 != rArg.nNoLineBreak )
393cdf0e10cSrcweir rArg.NewWord();
394cdf0e10cSrcweir if( nStop == nIdx )
395cdf0e10cSrcweir ++nStop;
396cdf0e10cSrcweir if( nStop > nEnd )
397cdf0e10cSrcweir nStop = nEnd;
398cdf0e10cSrcweir }
399cdf0e10cSrcweir else
400cdf0e10cSrcweir {
401cdf0e10cSrcweir while( nStop < nEnd && CH_BLANK != rTxt.GetChar( nStop ) )
402cdf0e10cSrcweir ++nStop;
403cdf0e10cSrcweir bClear = nStop == nIdx;
404cdf0e10cSrcweir if ( bClear )
405cdf0e10cSrcweir {
406cdf0e10cSrcweir rArg.NewWord();
407cdf0e10cSrcweir while( nStop < nEnd && CH_BLANK == rTxt.GetChar( nStop ) )
408cdf0e10cSrcweir ++nStop;
409cdf0e10cSrcweir }
410cdf0e10cSrcweir }
411cdf0e10cSrcweir
412cdf0e10cSrcweir SwDrawTextInfo aDrawInf( rArg.pSh, *rArg.pOut, 0, rTxt, nIdx, nStop - nIdx );
413cdf0e10cSrcweir long nAktWidth = pFnt->_GetTxtSize( aDrawInf ).Width();
414cdf0e10cSrcweir rArg.nRowWidth += nAktWidth;
415cdf0e10cSrcweir if( bClear )
416cdf0e10cSrcweir rArg.NewWord();
417cdf0e10cSrcweir else
418cdf0e10cSrcweir {
419cdf0e10cSrcweir rArg.nWordWidth += nAktWidth;
420cdf0e10cSrcweir if( (long)rArg.rAbsMin < rArg.nWordWidth )
421cdf0e10cSrcweir rArg.rAbsMin = rArg.nWordWidth;
422cdf0e10cSrcweir rArg.Minimum( rArg.nWordWidth + rArg.nWordAdd );
423cdf0e10cSrcweir bRet = sal_True;
424cdf0e10cSrcweir }
425cdf0e10cSrcweir nIdx = nStop;
426cdf0e10cSrcweir }
427cdf0e10cSrcweir return bRet;
428cdf0e10cSrcweir }
429cdf0e10cSrcweir
IsSymbol(const xub_StrLen nBegin) const430cdf0e10cSrcweir sal_Bool SwTxtNode::IsSymbol( const xub_StrLen nBegin ) const//swmodtest 080307
431cdf0e10cSrcweir {
432cdf0e10cSrcweir SwScriptInfo aScriptInfo;
433cdf0e10cSrcweir SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
434cdf0e10cSrcweir aIter.Seek( nBegin );
435cdf0e10cSrcweir return aIter.GetFnt()->IsSymbol(
436cdf0e10cSrcweir const_cast<ViewShell *>(getIDocumentLayoutAccess()->GetCurrentViewShell()) );//swmod 080311
437cdf0e10cSrcweir }
438cdf0e10cSrcweir
439cdf0e10cSrcweir class SwMinMaxNodeArgs
440cdf0e10cSrcweir {
441cdf0e10cSrcweir public:
442cdf0e10cSrcweir sal_uLong nMaxWidth; // Summe aller Rahmenbreite
443cdf0e10cSrcweir long nMinWidth; // Breitester Rahmen
444cdf0e10cSrcweir long nLeftRest; // noch nicht von Rahmen ueberdeckter Platz im l. Rand
445cdf0e10cSrcweir long nRightRest; // noch nicht von Rahmen ueberdeckter Platz im r. Rand
446cdf0e10cSrcweir long nLeftDiff; // Min/Max-Differenz des Rahmens im linken Rand
447cdf0e10cSrcweir long nRightDiff; // Min/Max-Differenz des Rahmens im rechten Rand
448cdf0e10cSrcweir sal_uLong nIndx; // Indexnummer des Nodes
Minimum(long nNew)449cdf0e10cSrcweir void Minimum( long nNew ) { if( nNew > nMinWidth ) nMinWidth = nNew; }
450cdf0e10cSrcweir };
451cdf0e10cSrcweir
lcl_MinMaxNode(const SwFrmFmtPtr & rpNd,void * pArgs)452cdf0e10cSrcweir sal_Bool lcl_MinMaxNode( const SwFrmFmtPtr& rpNd, void* pArgs )
453cdf0e10cSrcweir {
454cdf0e10cSrcweir const SwFmtAnchor& rFmtA = ((SwFrmFmt*)rpNd)->GetAnchor();
455cdf0e10cSrcweir
456cdf0e10cSrcweir bool bCalculate = false;
457cdf0e10cSrcweir if ((FLY_AT_PARA == rFmtA.GetAnchorId()) ||
458cdf0e10cSrcweir (FLY_AT_CHAR == rFmtA.GetAnchorId()))
459cdf0e10cSrcweir {
460cdf0e10cSrcweir bCalculate = true;
461cdf0e10cSrcweir }
462cdf0e10cSrcweir
463cdf0e10cSrcweir if (bCalculate)
464cdf0e10cSrcweir {
465cdf0e10cSrcweir const SwMinMaxNodeArgs *pIn = (const SwMinMaxNodeArgs*)pArgs;
466cdf0e10cSrcweir const SwPosition *pPos = rFmtA.GetCntntAnchor();
467cdf0e10cSrcweir ASSERT(pPos && pIn, "Unexpected NULL arguments");
468cdf0e10cSrcweir if (!pPos || !pIn || pIn->nIndx != pPos->nNode.GetIndex())
469cdf0e10cSrcweir bCalculate = false;
470cdf0e10cSrcweir }
471cdf0e10cSrcweir
472cdf0e10cSrcweir if (bCalculate)
473cdf0e10cSrcweir {
474cdf0e10cSrcweir long nMin, nMax;
475cdf0e10cSrcweir SwHTMLTableLayout *pLayout = 0;
476cdf0e10cSrcweir MSHORT nWhich = ((SwFrmFmt*)rpNd)->Which();
477cdf0e10cSrcweir if( RES_DRAWFRMFMT != nWhich )
478cdf0e10cSrcweir {
479cdf0e10cSrcweir // Enthaelt der Rahmen zu Beginn oder am Ende eine Tabelle?
480cdf0e10cSrcweir const SwNodes& rNodes = static_cast<SwFrmFmt*>(rpNd)->GetDoc()->GetNodes();
481cdf0e10cSrcweir const SwFmtCntnt& rFlyCntnt = ((SwFrmFmt*)rpNd)->GetCntnt();
482cdf0e10cSrcweir sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
483cdf0e10cSrcweir SwTableNode* pTblNd = rNodes[nStt+1]->GetTableNode();
484cdf0e10cSrcweir if( !pTblNd )
485cdf0e10cSrcweir {
486cdf0e10cSrcweir SwNode *pNd = rNodes[nStt];
487cdf0e10cSrcweir pNd = rNodes[pNd->EndOfSectionIndex()-1];
488cdf0e10cSrcweir if( pNd->IsEndNode() )
489cdf0e10cSrcweir pTblNd = pNd->StartOfSectionNode()->GetTableNode();
490cdf0e10cSrcweir }
491cdf0e10cSrcweir
492cdf0e10cSrcweir if( pTblNd )
493cdf0e10cSrcweir pLayout = pTblNd->GetTable().GetHTMLTableLayout();
494cdf0e10cSrcweir }
495cdf0e10cSrcweir
496cdf0e10cSrcweir const SwFmtHoriOrient& rOrient = ((SwFrmFmt*)rpNd)->GetHoriOrient();
497cdf0e10cSrcweir sal_Int16 eHoriOri = rOrient.GetHoriOrient();
498cdf0e10cSrcweir
499cdf0e10cSrcweir long nDiff;
500cdf0e10cSrcweir if( pLayout )
501cdf0e10cSrcweir {
502cdf0e10cSrcweir nMin = pLayout->GetMin();
503cdf0e10cSrcweir nMax = pLayout->GetMax();
504cdf0e10cSrcweir nDiff = nMax - nMin;
505cdf0e10cSrcweir }
506cdf0e10cSrcweir else
507cdf0e10cSrcweir {
508cdf0e10cSrcweir if( RES_DRAWFRMFMT == nWhich )
509cdf0e10cSrcweir {
510cdf0e10cSrcweir const SdrObject* pSObj = rpNd->FindSdrObject();
511cdf0e10cSrcweir if( pSObj )
512cdf0e10cSrcweir nMin = pSObj->GetCurrentBoundRect().GetWidth();
513cdf0e10cSrcweir else
514cdf0e10cSrcweir nMin = 0;
515cdf0e10cSrcweir
516cdf0e10cSrcweir }
517cdf0e10cSrcweir else
518cdf0e10cSrcweir {
519cdf0e10cSrcweir const SwFmtFrmSize &rSz = ( (SwFrmFmt*)rpNd )->GetFrmSize();
520cdf0e10cSrcweir nMin = rSz.GetWidth();
521cdf0e10cSrcweir }
522cdf0e10cSrcweir nMax = nMin;
523cdf0e10cSrcweir nDiff = 0;
524cdf0e10cSrcweir }
525cdf0e10cSrcweir
526cdf0e10cSrcweir const SvxLRSpaceItem &rLR = ( (SwFrmFmt*)rpNd )->GetLRSpace();
527cdf0e10cSrcweir nMin += rLR.GetLeft();
528cdf0e10cSrcweir nMin += rLR.GetRight();
529cdf0e10cSrcweir nMax += rLR.GetLeft();
530cdf0e10cSrcweir nMax += rLR.GetRight();
531cdf0e10cSrcweir
532cdf0e10cSrcweir if( SURROUND_THROUGHT == ((SwFrmFmt*)rpNd)->GetSurround().GetSurround() )
533cdf0e10cSrcweir {
534cdf0e10cSrcweir ( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
535cdf0e10cSrcweir return sal_True;
536cdf0e10cSrcweir }
537cdf0e10cSrcweir
538cdf0e10cSrcweir // Rahmen, die recht bzw. links ausgerichtet sind, gehen nur
539cdf0e10cSrcweir // teilweise in die Max-Berechnung ein, da der Rand schon berueck-
540cdf0e10cSrcweir // sichtigt wird. Nur wenn die Rahmen in den Textkoerper ragen,
541cdf0e10cSrcweir // wird dieser Teil hinzuaddiert.
542cdf0e10cSrcweir switch( eHoriOri )
543cdf0e10cSrcweir {
544cdf0e10cSrcweir case text::HoriOrientation::RIGHT:
545cdf0e10cSrcweir {
546cdf0e10cSrcweir if( nDiff )
547cdf0e10cSrcweir {
548cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nRightRest -=
549cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nRightDiff;
550cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nRightDiff = nDiff;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() )
553cdf0e10cSrcweir {
554cdf0e10cSrcweir if( ((SwMinMaxNodeArgs*)pArgs)->nRightRest > 0 )
555cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nRightRest = 0;
556cdf0e10cSrcweir }
557cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nRightRest -= nMin;
558cdf0e10cSrcweir break;
559cdf0e10cSrcweir }
560cdf0e10cSrcweir case text::HoriOrientation::LEFT:
561cdf0e10cSrcweir {
562cdf0e10cSrcweir if( nDiff )
563cdf0e10cSrcweir {
564cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nLeftRest -=
565cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nLeftDiff;
566cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nLeftDiff = nDiff;
567cdf0e10cSrcweir }
568cdf0e10cSrcweir if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() &&
569cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nLeftRest < 0 )
570cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nLeftRest = 0;
571cdf0e10cSrcweir ((SwMinMaxNodeArgs*)pArgs)->nLeftRest -= nMin;
572cdf0e10cSrcweir break;
573cdf0e10cSrcweir }
574cdf0e10cSrcweir default:
575cdf0e10cSrcweir {
576cdf0e10cSrcweir ( (SwMinMaxNodeArgs*)pArgs )->nMaxWidth += nMax;
577cdf0e10cSrcweir ( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
578cdf0e10cSrcweir }
579cdf0e10cSrcweir }
580cdf0e10cSrcweir }
581cdf0e10cSrcweir return sal_True;
582cdf0e10cSrcweir }
583cdf0e10cSrcweir
584cdf0e10cSrcweir #define FLYINCNT_MIN_WIDTH 284
585cdf0e10cSrcweir
586cdf0e10cSrcweir // changing this method very likely requires changing of
587cdf0e10cSrcweir // "GetScalingOfSelectedText"
GetMinMaxSize(sal_uLong nIndex,sal_uLong & rMin,sal_uLong & rMax,sal_uLong & rAbsMin,OutputDevice * pOut) const588cdf0e10cSrcweir void SwTxtNode::GetMinMaxSize( sal_uLong nIndex, sal_uLong& rMin, sal_uLong &rMax,
589cdf0e10cSrcweir sal_uLong& rAbsMin, OutputDevice* pOut ) const
590cdf0e10cSrcweir {
591cdf0e10cSrcweir ViewShell* pSh = 0;
592cdf0e10cSrcweir GetDoc()->GetEditShell( &pSh );
593cdf0e10cSrcweir if( !pOut )
594cdf0e10cSrcweir {
595cdf0e10cSrcweir if( pSh )
596cdf0e10cSrcweir pOut = pSh->GetWin();
597cdf0e10cSrcweir if( !pOut )
598cdf0e10cSrcweir pOut = GetpApp()->GetDefaultDevice();
599cdf0e10cSrcweir }
600cdf0e10cSrcweir
601cdf0e10cSrcweir MapMode aOldMap( pOut->GetMapMode() );
602cdf0e10cSrcweir pOut->SetMapMode( MapMode( MAP_TWIP ) );
603cdf0e10cSrcweir
604cdf0e10cSrcweir rMin = 0;
605cdf0e10cSrcweir rMax = 0;
606cdf0e10cSrcweir rAbsMin = 0;
607cdf0e10cSrcweir
608cdf0e10cSrcweir const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
609cdf0e10cSrcweir long nLROffset = rSpace.GetTxtLeft() + GetLeftMarginWithNum( sal_True );
610cdf0e10cSrcweir short nFLOffs;
611cdf0e10cSrcweir // Bei Numerierung ist ein neg. Erstzeileneinzug vermutlich
612cdf0e10cSrcweir // bereits gefuellt...
613cdf0e10cSrcweir if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
614cdf0e10cSrcweir nLROffset = nFLOffs;
615cdf0e10cSrcweir
616cdf0e10cSrcweir SwMinMaxNodeArgs aNodeArgs;
617cdf0e10cSrcweir aNodeArgs.nMinWidth = 0;
618cdf0e10cSrcweir aNodeArgs.nMaxWidth = 0;
619cdf0e10cSrcweir aNodeArgs.nLeftRest = nLROffset;
620cdf0e10cSrcweir aNodeArgs.nRightRest = rSpace.GetRight();
621cdf0e10cSrcweir aNodeArgs.nLeftDiff = 0;
622cdf0e10cSrcweir aNodeArgs.nRightDiff = 0;
623cdf0e10cSrcweir if( nIndex )
624cdf0e10cSrcweir {
625cdf0e10cSrcweir SwSpzFrmFmts* pTmp = (SwSpzFrmFmts*)GetDoc()->GetSpzFrmFmts();
626cdf0e10cSrcweir if( pTmp )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir aNodeArgs.nIndx = nIndex;
629cdf0e10cSrcweir pTmp->ForEach( &lcl_MinMaxNode, &aNodeArgs );
630cdf0e10cSrcweir }
631cdf0e10cSrcweir }
632cdf0e10cSrcweir if( aNodeArgs.nLeftRest < 0 )
633cdf0e10cSrcweir aNodeArgs.Minimum( nLROffset - aNodeArgs.nLeftRest );
634cdf0e10cSrcweir aNodeArgs.nLeftRest -= aNodeArgs.nLeftDiff;
635cdf0e10cSrcweir if( aNodeArgs.nLeftRest < 0 )
636cdf0e10cSrcweir aNodeArgs.nMaxWidth -= aNodeArgs.nLeftRest;
637cdf0e10cSrcweir
638cdf0e10cSrcweir if( aNodeArgs.nRightRest < 0 )
639cdf0e10cSrcweir aNodeArgs.Minimum( rSpace.GetRight() - aNodeArgs.nRightRest );
640cdf0e10cSrcweir aNodeArgs.nRightRest -= aNodeArgs.nRightDiff;
641cdf0e10cSrcweir if( aNodeArgs.nRightRest < 0 )
642cdf0e10cSrcweir aNodeArgs.nMaxWidth -= aNodeArgs.nRightRest;
643cdf0e10cSrcweir
644cdf0e10cSrcweir SwScriptInfo aScriptInfo;
645cdf0e10cSrcweir SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
646cdf0e10cSrcweir xub_StrLen nIdx = 0;
647cdf0e10cSrcweir aIter.SeekAndChgAttrIter( nIdx, pOut );
648cdf0e10cSrcweir xub_StrLen nLen = m_Text.Len();
649cdf0e10cSrcweir long nAktWidth = 0;
650cdf0e10cSrcweir MSHORT nAdd = 0;
651cdf0e10cSrcweir SwMinMaxArgs aArg( pOut, pSh, rMin, rMax, rAbsMin );
652cdf0e10cSrcweir while( nIdx < nLen )
653cdf0e10cSrcweir {
654cdf0e10cSrcweir xub_StrLen nNextChg = aIter.GetNextAttr();
655cdf0e10cSrcweir xub_StrLen nStop = aScriptInfo.NextScriptChg( nIdx );
656cdf0e10cSrcweir if( nNextChg > nStop )
657cdf0e10cSrcweir nNextChg = nStop;
658cdf0e10cSrcweir SwTxtAttr *pHint = NULL;
659cdf0e10cSrcweir xub_Unicode cChar = CH_BLANK;
660cdf0e10cSrcweir nStop = nIdx;
661cdf0e10cSrcweir while( nStop < nLen && nStop < nNextChg &&
662cdf0e10cSrcweir CH_TAB != ( cChar = m_Text.GetChar( nStop ) ) &&
663cdf0e10cSrcweir CH_BREAK != cChar && CHAR_HARDBLANK != cChar &&
664cdf0e10cSrcweir CHAR_HARDHYPHEN != cChar && CHAR_SOFTHYPHEN != cChar &&
665cdf0e10cSrcweir !pHint )
666cdf0e10cSrcweir {
667cdf0e10cSrcweir if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
668cdf0e10cSrcweir || ( 0 == ( pHint = aIter.GetAttr( nStop ) ) ) )
669cdf0e10cSrcweir ++nStop;
670cdf0e10cSrcweir }
671cdf0e10cSrcweir if ( lcl_MinMaxString( aArg, aIter.GetFnt(), m_Text, nIdx, nStop ) )
672cdf0e10cSrcweir {
673cdf0e10cSrcweir nAdd = 20;
674cdf0e10cSrcweir }
675cdf0e10cSrcweir nIdx = nStop;
676cdf0e10cSrcweir aIter.SeekAndChgAttrIter( nIdx, pOut );
677cdf0e10cSrcweir switch( cChar )
678cdf0e10cSrcweir {
679cdf0e10cSrcweir case CH_BREAK :
680cdf0e10cSrcweir {
681cdf0e10cSrcweir if( (long)rMax < aArg.nRowWidth )
682cdf0e10cSrcweir rMax = aArg.nRowWidth;
683cdf0e10cSrcweir aArg.nRowWidth = 0;
684cdf0e10cSrcweir aArg.NewWord();
685cdf0e10cSrcweir aIter.SeekAndChgAttrIter( ++nIdx, pOut );
686cdf0e10cSrcweir }
687cdf0e10cSrcweir break;
688cdf0e10cSrcweir case CH_TAB :
689cdf0e10cSrcweir {
690cdf0e10cSrcweir aArg.NewWord();
691cdf0e10cSrcweir aIter.SeekAndChgAttrIter( ++nIdx, pOut );
692cdf0e10cSrcweir }
693cdf0e10cSrcweir break;
694cdf0e10cSrcweir case CHAR_SOFTHYPHEN:
695cdf0e10cSrcweir ++nIdx;
696cdf0e10cSrcweir break;
697cdf0e10cSrcweir case CHAR_HARDBLANK:
698cdf0e10cSrcweir case CHAR_HARDHYPHEN:
699cdf0e10cSrcweir {
700cdf0e10cSrcweir XubString sTmp( cChar );
701cdf0e10cSrcweir SwDrawTextInfo aDrawInf( const_cast<ViewShell *>(getIDocumentLayoutAccess()->GetCurrentViewShell()),
702cdf0e10cSrcweir *pOut, 0, sTmp, 0, 1, 0, sal_False );//swmod 080311
703cdf0e10cSrcweir nAktWidth = aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
704cdf0e10cSrcweir aArg.nWordWidth += nAktWidth;
705cdf0e10cSrcweir aArg.nRowWidth += nAktWidth;
706cdf0e10cSrcweir if( (long)rAbsMin < aArg.nWordWidth )
707cdf0e10cSrcweir rAbsMin = aArg.nWordWidth;
708cdf0e10cSrcweir aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
709cdf0e10cSrcweir aArg.nNoLineBreak = nIdx++;
710cdf0e10cSrcweir }
711cdf0e10cSrcweir break;
712cdf0e10cSrcweir case CH_TXTATR_BREAKWORD:
713cdf0e10cSrcweir case CH_TXTATR_INWORD:
714cdf0e10cSrcweir {
715cdf0e10cSrcweir if( !pHint )
716cdf0e10cSrcweir break;
717cdf0e10cSrcweir long nOldWidth = aArg.nWordWidth;
718cdf0e10cSrcweir long nOldAdd = aArg.nWordAdd;
719cdf0e10cSrcweir aArg.NewWord();
720cdf0e10cSrcweir
721cdf0e10cSrcweir switch( pHint->Which() )
722cdf0e10cSrcweir {
723cdf0e10cSrcweir case RES_TXTATR_FLYCNT :
724cdf0e10cSrcweir {
725cdf0e10cSrcweir SwFrmFmt *pFrmFmt = pHint->GetFlyCnt().GetFrmFmt();
726cdf0e10cSrcweir const SvxLRSpaceItem &rLR = pFrmFmt->GetLRSpace();
727cdf0e10cSrcweir if( RES_DRAWFRMFMT == pFrmFmt->Which() )
728cdf0e10cSrcweir {
729cdf0e10cSrcweir const SdrObject* pSObj = pFrmFmt->FindSdrObject();
730cdf0e10cSrcweir if( pSObj )
731cdf0e10cSrcweir nAktWidth = pSObj->GetCurrentBoundRect().GetWidth();
732cdf0e10cSrcweir else
733cdf0e10cSrcweir nAktWidth = 0;
734cdf0e10cSrcweir }
735cdf0e10cSrcweir else
736cdf0e10cSrcweir {
737cdf0e10cSrcweir const SwFmtFrmSize& rTmpSize = pFrmFmt->GetFrmSize();
738cdf0e10cSrcweir if( RES_FLYFRMFMT == pFrmFmt->Which()
739cdf0e10cSrcweir && rTmpSize.GetWidthPercent() )
740cdf0e10cSrcweir {
741cdf0e10cSrcweir /*-----------------24.01.97 14:09----------------------------------------------
742cdf0e10cSrcweir * Hier ein HACK fuer folgende Situation: In dem Absatz befindet sich
743cdf0e10cSrcweir * ein Textrahmen mit relativer Groesse. Dann nehmen wir mal als minimale
744cdf0e10cSrcweir * Breite 0,5 cm und als maximale KSHRT_MAX.
745cdf0e10cSrcweir * Sauberer und vielleicht spaeter notwendig waere es, ueber den Inhalt
746cdf0e10cSrcweir * des Textrahmens zu iterieren und GetMinMaxSize rekursiv zu rufen.
747cdf0e10cSrcweir * --------------------------------------------------------------------------*/
748cdf0e10cSrcweir nAktWidth = FLYINCNT_MIN_WIDTH; // 0,5 cm
749cdf0e10cSrcweir if( (long)rMax < KSHRT_MAX )
750cdf0e10cSrcweir rMax = KSHRT_MAX;
751cdf0e10cSrcweir }
752cdf0e10cSrcweir else
753cdf0e10cSrcweir nAktWidth = pFrmFmt->GetFrmSize().GetWidth();
754cdf0e10cSrcweir }
755cdf0e10cSrcweir nAktWidth += rLR.GetLeft();
756cdf0e10cSrcweir nAktWidth += rLR.GetRight();
757cdf0e10cSrcweir aArg.nWordAdd = nOldWidth + nOldAdd;
758cdf0e10cSrcweir aArg.nWordWidth = nAktWidth;
759cdf0e10cSrcweir aArg.nRowWidth += nAktWidth;
760cdf0e10cSrcweir if( (long)rAbsMin < aArg.nWordWidth )
761cdf0e10cSrcweir rAbsMin = aArg.nWordWidth;
762cdf0e10cSrcweir aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
763cdf0e10cSrcweir break;
764cdf0e10cSrcweir }
765cdf0e10cSrcweir case RES_TXTATR_FTN :
766cdf0e10cSrcweir {
767cdf0e10cSrcweir const XubString aTxt = pHint->GetFtn().GetNumStr();
768cdf0e10cSrcweir if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
769cdf0e10cSrcweir aTxt.Len() ) )
770cdf0e10cSrcweir nAdd = 20;
771cdf0e10cSrcweir break;
772cdf0e10cSrcweir }
773dec99bbdSOliver-Rainer Wittmann
774dec99bbdSOliver-Rainer Wittmann case RES_TXTATR_FIELD :
775dec99bbdSOliver-Rainer Wittmann case RES_TXTATR_ANNOTATION :
776dec99bbdSOliver-Rainer Wittmann {
777dec99bbdSOliver-Rainer Wittmann SwField *pFld = (SwField*)pHint->GetFmtFld().GetField();
778dec99bbdSOliver-Rainer Wittmann const String aTxt = pFld->ExpandField(true);
779dec99bbdSOliver-Rainer Wittmann if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
780dec99bbdSOliver-Rainer Wittmann aTxt.Len() ) )
781dec99bbdSOliver-Rainer Wittmann nAdd = 20;
782dec99bbdSOliver-Rainer Wittmann break;
783dec99bbdSOliver-Rainer Wittmann }
784dec99bbdSOliver-Rainer Wittmann
785dec99bbdSOliver-Rainer Wittmann default: aArg.nWordWidth = nOldWidth;
786dec99bbdSOliver-Rainer Wittmann aArg.nWordAdd = nOldAdd;
787cdf0e10cSrcweir
788cdf0e10cSrcweir }
789cdf0e10cSrcweir aIter.SeekAndChgAttrIter( ++nIdx, pOut );
790cdf0e10cSrcweir }
791cdf0e10cSrcweir break;
792cdf0e10cSrcweir }
793cdf0e10cSrcweir }
794cdf0e10cSrcweir if( (long)rMax < aArg.nRowWidth )
795cdf0e10cSrcweir rMax = aArg.nRowWidth;
796cdf0e10cSrcweir
797cdf0e10cSrcweir nLROffset += rSpace.GetRight();
798cdf0e10cSrcweir
799cdf0e10cSrcweir rAbsMin += nLROffset;
800cdf0e10cSrcweir rAbsMin += nAdd;
801cdf0e10cSrcweir rMin += nLROffset;
802cdf0e10cSrcweir rMin += nAdd;
803cdf0e10cSrcweir if( (long)rMin < aNodeArgs.nMinWidth )
804cdf0e10cSrcweir rMin = aNodeArgs.nMinWidth;
805cdf0e10cSrcweir if( (long)rAbsMin < aNodeArgs.nMinWidth )
806cdf0e10cSrcweir rAbsMin = aNodeArgs.nMinWidth;
807cdf0e10cSrcweir rMax += aNodeArgs.nMaxWidth;
808cdf0e10cSrcweir rMax += nLROffset;
809cdf0e10cSrcweir rMax += nAdd;
810cdf0e10cSrcweir if( rMax < rMin ) // z.B. Rahmen mit Durchlauf gehen zunaechst nur
811cdf0e10cSrcweir rMax = rMin; // in das Minimum ein
812cdf0e10cSrcweir pOut->SetMapMode( aOldMap );
813cdf0e10cSrcweir }
814cdf0e10cSrcweir
815cdf0e10cSrcweir /*************************************************************************
816cdf0e10cSrcweir * SwTxtNode::GetScalingOfSelectedText()
817cdf0e10cSrcweir *
818cdf0e10cSrcweir * Calculates the width of the text part specified by nStt and nEnd,
819*86e1cf34SPedro Giffuni * the height of the line containing nStt is divided by this width,
820cdf0e10cSrcweir * indicating the scaling factor, if the text part is rotated.
821cdf0e10cSrcweir * Having CH_BREAKs in the text part, this method returns the scaling
822cdf0e10cSrcweir * factor for the longest of the text parts separated by the CH_BREAKs.
823cdf0e10cSrcweir *
824cdf0e10cSrcweir * changing this method very likely requires changing of "GetMinMaxSize"
825cdf0e10cSrcweir *************************************************************************/
826cdf0e10cSrcweir
GetScalingOfSelectedText(xub_StrLen nStt,xub_StrLen nEnd) const827cdf0e10cSrcweir sal_uInt16 SwTxtNode::GetScalingOfSelectedText( xub_StrLen nStt, xub_StrLen nEnd )
828cdf0e10cSrcweir const
829cdf0e10cSrcweir {
830cdf0e10cSrcweir ViewShell* pSh = NULL;
831cdf0e10cSrcweir OutputDevice* pOut = NULL;
832cdf0e10cSrcweir GetDoc()->GetEditShell( &pSh );
833cdf0e10cSrcweir
834cdf0e10cSrcweir if ( pSh )
835cdf0e10cSrcweir pOut = &pSh->GetRefDev();
836cdf0e10cSrcweir else
837cdf0e10cSrcweir {
838cdf0e10cSrcweir //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein.
839cdf0e10cSrcweir if ( getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) )
840cdf0e10cSrcweir pOut = GetpApp()->GetDefaultDevice();
841cdf0e10cSrcweir else
842cdf0e10cSrcweir pOut = getIDocumentDeviceAccess()->getReferenceDevice( true );
843cdf0e10cSrcweir }
844cdf0e10cSrcweir
845cdf0e10cSrcweir ASSERT( pOut, "GetScalingOfSelectedText without outdev" )
846cdf0e10cSrcweir
847cdf0e10cSrcweir MapMode aOldMap( pOut->GetMapMode() );
848cdf0e10cSrcweir pOut->SetMapMode( MapMode( MAP_TWIP ) );
849cdf0e10cSrcweir
850cdf0e10cSrcweir if ( nStt == nEnd )
851cdf0e10cSrcweir {
852cdf0e10cSrcweir if ( !pBreakIt->GetBreakIter().is() )
853cdf0e10cSrcweir return 100;
854cdf0e10cSrcweir
855cdf0e10cSrcweir SwScriptInfo aScriptInfo;
856cdf0e10cSrcweir SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
857cdf0e10cSrcweir aIter.SeekAndChgAttrIter( nStt, pOut );
858cdf0e10cSrcweir
859cdf0e10cSrcweir Boundary aBound =
860cdf0e10cSrcweir pBreakIt->GetBreakIter()->getWordBoundary( GetTxt(), nStt,
861cdf0e10cSrcweir pBreakIt->GetLocale( aIter.GetFnt()->GetLanguage() ),
862cdf0e10cSrcweir WordType::DICTIONARY_WORD, sal_True );
863cdf0e10cSrcweir
864cdf0e10cSrcweir if ( nStt == aBound.startPos )
865cdf0e10cSrcweir {
866cdf0e10cSrcweir // cursor is at left or right border of word
867cdf0e10cSrcweir pOut->SetMapMode( aOldMap );
868cdf0e10cSrcweir return 100;
869cdf0e10cSrcweir }
870cdf0e10cSrcweir
871cdf0e10cSrcweir nStt = (xub_StrLen)aBound.startPos;
872cdf0e10cSrcweir nEnd = (xub_StrLen)aBound.endPos;
873cdf0e10cSrcweir
874cdf0e10cSrcweir if ( nStt == nEnd )
875cdf0e10cSrcweir {
876cdf0e10cSrcweir pOut->SetMapMode( aOldMap );
877cdf0e10cSrcweir return 100;
878cdf0e10cSrcweir }
879cdf0e10cSrcweir }
880cdf0e10cSrcweir
881cdf0e10cSrcweir SwScriptInfo aScriptInfo;
882cdf0e10cSrcweir SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
883cdf0e10cSrcweir
884cdf0e10cSrcweir // We do not want scaling attributes to be considered during this
885cdf0e10cSrcweir // calculation. For this, we push a temporary scaling attribute with
886cdf0e10cSrcweir // scaling value 100 and priority flag on top of the scaling stack
887cdf0e10cSrcweir SwAttrHandler& rAH = aIter.GetAttrHandler();
888cdf0e10cSrcweir SvxCharScaleWidthItem aItem(100, RES_CHRATR_SCALEW);
889cdf0e10cSrcweir SwTxtAttrEnd aAttr( aItem, nStt, nEnd );
890cdf0e10cSrcweir aAttr.SetPriorityAttr( sal_True );
891cdf0e10cSrcweir rAH.PushAndChg( aAttr, *(aIter.GetFnt()) );
892cdf0e10cSrcweir
893cdf0e10cSrcweir xub_StrLen nIdx = nStt;
894cdf0e10cSrcweir
895cdf0e10cSrcweir sal_uLong nWidth = 0;
896cdf0e10cSrcweir sal_uLong nProWidth = 0;
897cdf0e10cSrcweir
898cdf0e10cSrcweir while( nIdx < nEnd )
899cdf0e10cSrcweir {
900cdf0e10cSrcweir aIter.SeekAndChgAttrIter( nIdx, pOut );
901cdf0e10cSrcweir
902cdf0e10cSrcweir // scan for end of portion
903cdf0e10cSrcweir xub_StrLen nNextChg = aIter.GetNextAttr();
904cdf0e10cSrcweir xub_StrLen nStop = aScriptInfo.NextScriptChg( nIdx );
905cdf0e10cSrcweir if( nNextChg > nStop )
906cdf0e10cSrcweir nNextChg = nStop;
907cdf0e10cSrcweir
908cdf0e10cSrcweir nStop = nIdx;
909cdf0e10cSrcweir xub_Unicode cChar = CH_BLANK;
910cdf0e10cSrcweir SwTxtAttr* pHint = NULL;
911cdf0e10cSrcweir
912cdf0e10cSrcweir // stop at special characters in [ nIdx, nNextChg ]
913cdf0e10cSrcweir while( nStop < nEnd && nStop < nNextChg )
914cdf0e10cSrcweir {
915cdf0e10cSrcweir cChar = m_Text.GetChar( nStop );
916cdf0e10cSrcweir if (
917cdf0e10cSrcweir CH_TAB == cChar ||
918cdf0e10cSrcweir CH_BREAK == cChar ||
919cdf0e10cSrcweir CHAR_HARDBLANK == cChar ||
920cdf0e10cSrcweir CHAR_HARDHYPHEN == cChar ||
921cdf0e10cSrcweir CHAR_SOFTHYPHEN == cChar ||
922cdf0e10cSrcweir (
923cdf0e10cSrcweir (CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar) &&
924cdf0e10cSrcweir (0 == (pHint = aIter.GetAttr(nStop)))
925cdf0e10cSrcweir )
926cdf0e10cSrcweir )
927cdf0e10cSrcweir {
928cdf0e10cSrcweir break;
929cdf0e10cSrcweir }
930cdf0e10cSrcweir else
931cdf0e10cSrcweir ++nStop;
932cdf0e10cSrcweir }
933cdf0e10cSrcweir
934cdf0e10cSrcweir // calculate text widths up to cChar
935cdf0e10cSrcweir if ( nStop > nIdx )
936cdf0e10cSrcweir {
937cdf0e10cSrcweir SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nIdx, nStop - nIdx );
938cdf0e10cSrcweir nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
939cdf0e10cSrcweir }
940cdf0e10cSrcweir
941cdf0e10cSrcweir nIdx = nStop;
942cdf0e10cSrcweir aIter.SeekAndChgAttrIter( nIdx, pOut );
943cdf0e10cSrcweir
944cdf0e10cSrcweir if ( cChar == CH_BREAK )
945cdf0e10cSrcweir {
946cdf0e10cSrcweir nWidth = Max( nWidth, nProWidth );
947cdf0e10cSrcweir nProWidth = 0;
948cdf0e10cSrcweir nIdx++;
949cdf0e10cSrcweir }
950cdf0e10cSrcweir else if ( cChar == CH_TAB )
951cdf0e10cSrcweir {
952cdf0e10cSrcweir // tab receives width of one space
953cdf0e10cSrcweir XubString sTmp( CH_BLANK );
954cdf0e10cSrcweir SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
955cdf0e10cSrcweir nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
956cdf0e10cSrcweir nIdx++;
957cdf0e10cSrcweir }
958cdf0e10cSrcweir else if ( cChar == CHAR_SOFTHYPHEN )
959cdf0e10cSrcweir ++nIdx;
960cdf0e10cSrcweir else if ( cChar == CHAR_HARDBLANK || cChar == CHAR_HARDHYPHEN )
961cdf0e10cSrcweir {
962cdf0e10cSrcweir XubString sTmp( cChar );
963cdf0e10cSrcweir SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
964cdf0e10cSrcweir nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
965dec99bbdSOliver-Rainer Wittmann nIdx++;
966cdf0e10cSrcweir }
967dec99bbdSOliver-Rainer Wittmann else if ( pHint && ( cChar == CH_TXTATR_BREAKWORD || CH_TXTATR_INWORD ) )
968dec99bbdSOliver-Rainer Wittmann {
969dec99bbdSOliver-Rainer Wittmann switch( pHint->Which() )
970dec99bbdSOliver-Rainer Wittmann {
971dec99bbdSOliver-Rainer Wittmann case RES_TXTATR_FTN :
972dec99bbdSOliver-Rainer Wittmann {
973dec99bbdSOliver-Rainer Wittmann const XubString aTxt = pHint->GetFtn().GetNumStr();
974cdf0e10cSrcweir SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.Len() );
975cdf0e10cSrcweir
976cdf0e10cSrcweir nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
977dec99bbdSOliver-Rainer Wittmann break;
978dec99bbdSOliver-Rainer Wittmann }
979dec99bbdSOliver-Rainer Wittmann
980dec99bbdSOliver-Rainer Wittmann case RES_TXTATR_FIELD :
981dec99bbdSOliver-Rainer Wittmann case RES_TXTATR_ANNOTATION :
982dec99bbdSOliver-Rainer Wittmann {
983dec99bbdSOliver-Rainer Wittmann SwField *pFld = (SwField*)pHint->GetFmtFld().GetField();
984cdf0e10cSrcweir String const aTxt = pFld->ExpandField(true);
985cdf0e10cSrcweir SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.Len() );
986cdf0e10cSrcweir
987cdf0e10cSrcweir nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
988dec99bbdSOliver-Rainer Wittmann break;
989dec99bbdSOliver-Rainer Wittmann }
990dec99bbdSOliver-Rainer Wittmann
991dec99bbdSOliver-Rainer Wittmann default:
992dec99bbdSOliver-Rainer Wittmann {
993dec99bbdSOliver-Rainer Wittmann // any suggestions for a default action?
994dec99bbdSOliver-Rainer Wittmann }
995dec99bbdSOliver-Rainer Wittmann } // end of switch
996dec99bbdSOliver-Rainer Wittmann nIdx++;
997dec99bbdSOliver-Rainer Wittmann } // end of while
998dec99bbdSOliver-Rainer Wittmann }
999cdf0e10cSrcweir
1000cdf0e10cSrcweir nWidth = Max( nWidth, nProWidth );
1001cdf0e10cSrcweir
1002cdf0e10cSrcweir // search for a text frame this node belongs to
1003cdf0e10cSrcweir SwIterator<SwTxtFrm,SwTxtNode> aFrmIter( *this );
1004cdf0e10cSrcweir SwTxtFrm* pFrm = 0;
1005cdf0e10cSrcweir for( SwTxtFrm* pTmpFrm = aFrmIter.First(); pTmpFrm; pTmpFrm = aFrmIter.Next() )
1006cdf0e10cSrcweir {
1007cdf0e10cSrcweir if ( pTmpFrm->GetOfst() <= nStt &&
1008cdf0e10cSrcweir ( !pTmpFrm->GetFollow() ||
1009cdf0e10cSrcweir pTmpFrm->GetFollow()->GetOfst() > nStt ) )
1010cdf0e10cSrcweir {
1011cdf0e10cSrcweir pFrm = pTmpFrm;
1012cdf0e10cSrcweir break;
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir }
1015cdf0e10cSrcweir
1016cdf0e10cSrcweir // search for the line containing nStt
1017cdf0e10cSrcweir if ( pFrm && pFrm->HasPara() )
1018cdf0e10cSrcweir {
1019cdf0e10cSrcweir SwTxtInfo aInf( pFrm );
1020cdf0e10cSrcweir SwTxtIter aLine( pFrm, &aInf );
1021cdf0e10cSrcweir aLine.CharToLine( nStt );
1022cdf0e10cSrcweir pOut->SetMapMode( aOldMap );
1023cdf0e10cSrcweir return (sal_uInt16)( nWidth ?
1024cdf0e10cSrcweir ( ( 100 * aLine.GetCurr()->Height() ) / nWidth ) : 0 );
1025cdf0e10cSrcweir }
1026cdf0e10cSrcweir // no frame or no paragraph, we take the height of the character
1027cdf0e10cSrcweir // at nStt as line height
1028cdf0e10cSrcweir
1029cdf0e10cSrcweir aIter.SeekAndChgAttrIter( nStt, pOut );
1030cdf0e10cSrcweir pOut->SetMapMode( aOldMap );
1031cdf0e10cSrcweir
1032cdf0e10cSrcweir SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nStt, 1 );
1033cdf0e10cSrcweir return (sal_uInt16)
1034cdf0e10cSrcweir ( nWidth ? ((100 * aIter.GetFnt()->_GetTxtSize( aDrawInf ).Height()) / nWidth ) : 0 );
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir
GetWidthOfLeadingTabs() const1037cdf0e10cSrcweir sal_uInt16 SwTxtNode::GetWidthOfLeadingTabs() const
1038cdf0e10cSrcweir {
1039cdf0e10cSrcweir sal_uInt16 nRet = 0;
1040cdf0e10cSrcweir
1041cdf0e10cSrcweir xub_StrLen nIdx = 0;
1042cdf0e10cSrcweir sal_Unicode cCh;
1043cdf0e10cSrcweir
1044cdf0e10cSrcweir while ( nIdx < GetTxt().Len() &&
1045cdf0e10cSrcweir ( '\t' == ( cCh = GetTxt().GetChar( nIdx ) ) ||
1046cdf0e10cSrcweir ' ' == cCh ) )
1047cdf0e10cSrcweir ++nIdx;
1048cdf0e10cSrcweir
1049cdf0e10cSrcweir if ( nIdx > 0 )
1050cdf0e10cSrcweir {
1051cdf0e10cSrcweir SwPosition aPos( *this );
1052cdf0e10cSrcweir aPos.nContent += nIdx;
1053cdf0e10cSrcweir
1054cdf0e10cSrcweir // Find the non-follow text frame:
1055cdf0e10cSrcweir SwIterator<SwTxtFrm,SwTxtNode> aIter( *this );
1056cdf0e10cSrcweir for( SwTxtFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
1057cdf0e10cSrcweir {
1058cdf0e10cSrcweir // Only consider master frames:
1059cdf0e10cSrcweir if ( !pFrm->IsFollow() )
1060cdf0e10cSrcweir {
1061cdf0e10cSrcweir SWRECTFN( pFrm )
1062cdf0e10cSrcweir SwRect aRect;
1063cdf0e10cSrcweir pFrm->GetCharRect( aRect, aPos );
1064cdf0e10cSrcweir nRet = (sal_uInt16)
1065cdf0e10cSrcweir ( pFrm->IsRightToLeft() ?
1066cdf0e10cSrcweir (pFrm->*fnRect->fnGetPrtRight)() - (aRect.*fnRect->fnGetRight)() :
1067cdf0e10cSrcweir (aRect.*fnRect->fnGetLeft)() - (pFrm->*fnRect->fnGetPrtLeft)() );
1068cdf0e10cSrcweir break;
1069cdf0e10cSrcweir }
1070cdf0e10cSrcweir }
1071cdf0e10cSrcweir }
1072cdf0e10cSrcweir
1073cdf0e10cSrcweir return nRet;
1074cdf0e10cSrcweir }
1075