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