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 <vcl/metric.hxx>
31 : : #include <vcl/window.hxx>
32 : : #include <vcl/svapp.hxx>
33 : : #include <paratr.hxx>
34 : : #include <txtfrm.hxx> // Format()
35 : : #include <charfmt.hxx>
36 : : #include <viewopt.hxx> // SwViewOption
37 : : #include <viewsh.hxx> // ViewShell
38 : : #include <pordrop.hxx>
39 : : #include <itrform2.hxx>
40 : : #include <txtpaint.hxx> // SwSaveClip
41 : : #include <blink.hxx> // pBlink
42 : : #include <breakit.hxx>
43 : : #include <com/sun/star/i18n/ScriptType.hpp>
44 : : #include <com/sun/star/i18n/WordType.hpp>
45 : : #include <editeng/langitem.hxx>
46 : : #include <charatr.hxx>
47 : : #include <editeng/fhgtitem.hxx>
48 : : #include <switerator.hxx>
49 : :
50 : : using namespace ::com::sun::star::i18n;
51 : : using namespace ::com::sun::star;
52 : :
53 : : /*************************************************************************
54 : : * lcl_IsDropFlyInter
55 : : *
56 : : * Calculates if a drop caps portion intersects with a fly
57 : : * The width and height of the drop caps portion are passed as arguments,
58 : : * the position is calculated from the values in rInf
59 : : *************************************************************************/
60 : :
61 : 0 : sal_Bool lcl_IsDropFlyInter( const SwTxtFormatInfo &rInf,
62 : : sal_uInt16 nWidth, sal_uInt16 nHeight )
63 : : {
64 : 0 : const SwTxtFly *pTxtFly = rInf.GetTxtFly();
65 [ # # ][ # # ]: 0 : if( pTxtFly && pTxtFly->IsOn() )
[ # # ]
66 : : {
67 : 0 : SwRect aRect( rInf.GetTxtFrm()->Frm().Pos(), Size( nWidth, nHeight) );
68 : 0 : aRect.Pos() += rInf.GetTxtFrm()->Prt().Pos();
69 : 0 : aRect.Pos().X() += rInf.X();
70 : 0 : aRect.Pos().Y() = rInf.Y();
71 [ # # ]: 0 : aRect = pTxtFly->GetFrm( aRect );
72 [ # # ]: 0 : return aRect.HasArea();
73 : : }
74 : :
75 : 0 : return sal_False;
76 : : }
77 : :
78 : : /*************************************************************************
79 : : * class SwDropSave
80 : : *************************************************************************/
81 : :
82 : : class SwDropSave
83 : : {
84 : : SwTxtPaintInfo* pInf;
85 : : xub_StrLen nIdx;
86 : : xub_StrLen nLen;
87 : : long nX;
88 : : long nY;
89 : :
90 : : public:
91 : : SwDropSave( const SwTxtPaintInfo &rInf );
92 : : ~SwDropSave();
93 : : };
94 : :
95 : 0 : SwDropSave::SwDropSave( const SwTxtPaintInfo &rInf ) :
96 : 0 : pInf( ((SwTxtPaintInfo*)&rInf) ), nIdx( rInf.GetIdx() ),
97 : 0 : nLen( rInf.GetLen() ), nX( rInf.X() ), nY( rInf.Y() )
98 : : {
99 : 0 : }
100 : :
101 : 0 : SwDropSave::~SwDropSave()
102 : : {
103 : 0 : pInf->SetIdx( nIdx );
104 : 0 : pInf->SetLen( nLen );
105 : 0 : pInf->X( nX );
106 : 0 : pInf->Y( nY );
107 : 0 : }
108 : :
109 : : /*************************************************************************
110 : : * SwDropPortionPart DTor
111 : : *************************************************************************/
112 : :
113 : 0 : SwDropPortionPart::~SwDropPortionPart()
114 : : {
115 [ # # ]: 0 : delete pFollow;
116 [ # # ]: 0 : delete pFnt;
117 : 0 : }
118 : :
119 : : /*************************************************************************
120 : : * SwDropPortion CTor, DTor
121 : : *************************************************************************/
122 : :
123 : 0 : SwDropPortion::SwDropPortion( const MSHORT nLineCnt,
124 : : const KSHORT nDrpHeight,
125 : : const KSHORT nDrpDescent,
126 : : const KSHORT nDist )
127 : : : pPart( 0 ),
128 : : nLines( nLineCnt ),
129 : : nDropHeight(nDrpHeight),
130 : : nDropDescent(nDrpDescent),
131 : : nDistance(nDist),
132 : : nFix(0),
133 : 0 : nX(0)
134 : : {
135 : 0 : SetWhichPor( POR_DROP );
136 : 0 : }
137 : :
138 : 0 : SwDropPortion::~SwDropPortion()
139 : : {
140 [ # # ][ # # ]: 0 : delete pPart;
141 [ # # ]: 0 : if( pBlink )
142 [ # # ]: 0 : pBlink->Delete( this );
143 [ # # ]: 0 : }
144 : :
145 : 2851 : sal_Bool SwTxtSizeInfo::_HasHint( const SwTxtNode* pTxtNode, xub_StrLen nPos )
146 : : {
147 : 2851 : return 0 != pTxtNode->GetTxtAttrForCharAt(nPos);
148 : : }
149 : :
150 : : /*************************************************************************
151 : : * SwTxtNode::GetDropLen()
152 : : *
153 : : * nWishLen = 0 indicates that we want a whole word
154 : : *************************************************************************/
155 : :
156 : 0 : MSHORT SwTxtNode::GetDropLen( MSHORT nWishLen ) const
157 : : {
158 : 0 : xub_StrLen nEnd = GetTxt().Len();
159 [ # # ][ # # ]: 0 : if( nWishLen && nWishLen < nEnd )
160 : 0 : nEnd = nWishLen;
161 : :
162 [ # # ][ # # ]: 0 : if ( ! nWishLen && pBreakIt->GetBreakIter().is() )
[ # # ][ # # ]
[ # # # # ]
163 : : {
164 : : // find first word
165 [ # # ]: 0 : const SwAttrSet& rAttrSet = GetSwAttrSet();
166 [ # # ][ # # ]: 0 : const sal_uInt16 nTxtScript = pBreakIt->GetRealScriptOfText( GetTxt(), 0 );
167 : :
168 : : LanguageType eLanguage;
169 : :
170 [ # # # ]: 0 : switch ( nTxtScript )
171 : : {
172 : : case i18n::ScriptType::ASIAN :
173 [ # # ]: 0 : eLanguage = rAttrSet.GetCJKLanguage().GetLanguage();
174 : 0 : break;
175 : : case i18n::ScriptType::COMPLEX :
176 [ # # ]: 0 : eLanguage = rAttrSet.GetCTLLanguage().GetLanguage();
177 : 0 : break;
178 : : default :
179 [ # # ]: 0 : eLanguage = rAttrSet.GetLanguage().GetLanguage();
180 : 0 : break;
181 : : }
182 : :
183 : : Boundary aBound =
184 [ # # ][ # # ]: 0 : pBreakIt->GetBreakIter()->getWordBoundary( GetTxt(), 0,
185 [ # # # # ]: 0 : pBreakIt->GetLocale( eLanguage ), WordType::DICTIONARY_WORD, sal_True );
[ # # ]
186 : :
187 : 0 : nEnd = (xub_StrLen)aBound.endPos;
188 : : }
189 : :
190 : 0 : xub_StrLen i = 0;
191 [ # # ]: 0 : for( ; i < nEnd; ++i )
192 : : {
193 : 0 : xub_Unicode cChar = GetTxt().GetChar( i );
194 [ # # ][ # # ]: 0 : if( CH_TAB == cChar || CH_BREAK == cChar ||
[ # # # # ]
[ # # ][ # # ]
195 : : (( CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar )
196 : 0 : && SwTxtSizeInfo::_HasHint( this, i ) ) )
197 : 0 : break;
198 : : }
199 : 0 : return i;
200 : : }
201 : :
202 : : /*************************************************************************
203 : : * SwTxtNode::GetDropSize()
204 : : *
205 : : * If a dropcap is found the return value is true otherwise false. The
206 : : * drop cap sizes passed back by reference are font height, drop height
207 : : * and drop descent.
208 : : *************************************************************************/
209 : 0 : bool SwTxtNode::GetDropSize(int& rFontHeight, int& rDropHeight, int& rDropDescent) const
210 : : {
211 : 0 : rFontHeight = 0;
212 : 0 : rDropHeight = 0;
213 : 0 : rDropDescent =0;
214 : :
215 [ # # ]: 0 : const SwAttrSet& rSet = GetSwAttrSet();
216 [ # # ]: 0 : const SwFmtDrop& rDrop = rSet.GetDrop();
217 : :
218 : : // Return (0,0) if there is no drop cap at this paragraph
219 [ # # # # : 0 : if( 1 >= rDrop.GetLines() ||
# # ][ # # ]
220 : 0 : ( !rDrop.GetChars() && !rDrop.GetWholeWord() ) )
221 : : {
222 : 0 : return false;
223 : : }
224 : :
225 : : // get text frame
226 [ # # ]: 0 : SwIterator<SwTxtFrm,SwTxtNode> aIter( *this );
227 [ # # ][ # # ]: 0 : for( SwTxtFrm* pLastFrm = aIter.First(); pLastFrm; pLastFrm = aIter.Next() )
[ # # ]
228 : : {
229 : : // Only (master-) text frames can have a drop cap.
230 [ # # ]: 0 : if ( !pLastFrm->IsFollow() )
231 : : {
232 : :
233 [ # # ][ # # ]: 0 : if( !pLastFrm->HasPara() )
234 [ # # ]: 0 : pLastFrm->GetFormatted();
235 : :
236 [ # # ]: 0 : if ( !pLastFrm->IsEmpty() )
237 : : {
238 [ # # ]: 0 : const SwParaPortion* pPara = pLastFrm->GetPara();
239 : : OSL_ENSURE( pPara, "GetDropSize could not find the ParaPortion, I'll guess the drop cap size" );
240 : :
241 [ # # ]: 0 : if ( pPara )
242 : : {
243 : 0 : const SwLinePortion* pFirstPor = pPara->GetFirstPortion();
244 [ # # ][ # # ]: 0 : if (pFirstPor && pFirstPor->IsDropPortion())
[ # # ]
245 : : {
246 : 0 : const SwDropPortion* pDrop = (const SwDropPortion*)pFirstPor;
247 : 0 : rDropHeight = pDrop->GetDropHeight();
248 : 0 : rDropDescent = pDrop->GetDropDescent();
249 [ # # ]: 0 : if (const SwFont *pFont = pDrop->GetFnt())
250 : 0 : rFontHeight = pFont->GetSize(pFont->GetActual()).Height();
251 : : else
252 : : {
253 [ # # ]: 0 : const SvxFontHeightItem& rItem = (SvxFontHeightItem&)rSet.Get(RES_CHRATR_FONTSIZE);
254 : 0 : rFontHeight = rItem.GetHeight();
255 : : }
256 : : }
257 : : }
258 : : }
259 : 0 : break;
260 : : }
261 : : }
262 : :
263 [ # # ][ # # ]: 0 : if (rFontHeight==0 && rDropHeight==0 && rDropDescent==0)
[ # # ]
264 : : {
265 : 0 : const sal_uInt16 nLines = rDrop.GetLines();
266 : :
267 [ # # ]: 0 : const SvxFontHeightItem& rItem = (SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE );
268 : 0 : rFontHeight = rItem.GetHeight();
269 : 0 : rDropHeight = nLines * rFontHeight;
270 : 0 : rDropDescent = rFontHeight / 5;
271 : 0 : return false;
272 : : }
273 : :
274 [ # # ]: 0 : return true;
275 : : }
276 : :
277 : : /*************************************************************************
278 : : * SwDropPortion::PaintTxt()
279 : : *************************************************************************/
280 : :
281 : : // Die Breite manipulieren, sonst werden die Buchstaben gestretcht
282 : :
283 : 0 : void SwDropPortion::PaintTxt( const SwTxtPaintInfo &rInf ) const
284 : : {
285 [ # # # # : 0 : if ( rInf.OnWin() &&
# # ][ # # ]
[ # # ]
286 [ # # ]: 0 : !rInf.GetOpt().IsPagePreview() && !rInf.GetOpt().IsReadonly() && SwViewOption::IsFieldShadings() )
287 [ # # ]: 0 : rInf.DrawBackground( *this );
288 : :
289 : : OSL_ENSURE( nDropHeight && pPart && nLines != 1, "Drop Portion painted twice" );
290 : :
291 : 0 : const SwDropPortionPart* pCurrPart = GetPart();
292 : 0 : const xub_StrLen nOldLen = GetLen();
293 : :
294 : 0 : const SwTwips nBasePosY = rInf.Y();
295 : 0 : ((SwTxtPaintInfo&)rInf).Y( nBasePosY + nY );
296 : 0 : SwDropSave aSave( rInf );
297 : : // for text inside drop portions we let vcl handle the text directions
298 [ # # ]: 0 : SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
299 [ # # ]: 0 : aLayoutModeModifier.SetAuto();
300 : :
301 [ # # ]: 0 : while ( pCurrPart )
302 : : {
303 : 0 : ((SwDropPortion*)this)->SetLen( pCurrPart->GetLen() );
304 : 0 : ((SwTxtPaintInfo&)rInf).SetLen( pCurrPart->GetLen() );
305 [ # # ]: 0 : SwFontSave aFontSave( rInf, &pCurrPart->GetFont() );
306 : :
307 [ # # ]: 0 : SwTxtPortion::Paint( rInf );
308 : :
309 : 0 : ((SwTxtPaintInfo&)rInf).SetIdx( rInf.GetIdx() + pCurrPart->GetLen() );
310 : 0 : ((SwTxtPaintInfo&)rInf).X( rInf.X() + pCurrPart->GetWidth() );
311 : 0 : pCurrPart = pCurrPart->GetFollow();
312 [ # # ]: 0 : }
313 : :
314 : 0 : ((SwTxtPaintInfo&)rInf).Y( nBasePosY );
315 [ # # ]: 0 : ((SwDropPortion*)this)->SetLen( nOldLen );
316 : 0 : }
317 : :
318 : : /*************************************************************************
319 : : * SwDropPortion::Paint()
320 : : *************************************************************************/
321 : :
322 : 0 : void SwDropPortion::PaintDrop( const SwTxtPaintInfo &rInf ) const
323 : : {
324 : : // ganz normale Ausgabe wird w?hrend des normalen Paints erledigt
325 [ # # ][ # # ]: 0 : if( ! nDropHeight || ! pPart || nLines == 1 )
[ # # ]
326 : 0 : return;
327 : :
328 : : // Luegenwerte einstellen!
329 : 0 : const KSHORT nOldHeight = Height();
330 : 0 : const KSHORT nOldWidth = Width();
331 : 0 : const KSHORT nOldAscent = GetAscent();
332 : 0 : const SwTwips nOldPosY = rInf.Y();
333 : 0 : const KSHORT nOldPosX = (KSHORT)rInf.X();
334 : 0 : const SwParaPortion *pPara = rInf.GetParaPortion();
335 : 0 : const Point aOutPos( nOldPosX + nX, nOldPosY - pPara->GetAscent()
336 : 0 : - pPara->GetRealHeight() + pPara->Height() );
337 : : // Retusche nachholen.
338 : :
339 : : // Set baseline
340 : 0 : ((SwTxtPaintInfo&)rInf).Y( aOutPos.Y() + nDropHeight );
341 : :
342 : : // for background
343 : 0 : ((SwDropPortion*)this)->Height( nDropHeight + nDropDescent );
344 : 0 : ((SwDropPortion*)this)->Width( Width() - nX );
345 : 0 : ((SwDropPortion*)this)->SetAscent( nDropHeight );
346 : :
347 : : // Clipregion auf uns einstellen!
348 : : // Und zwar immer, und nie mit dem bestehenden ClipRect
349 : : // verrechnen, weil dies auf die Zeile eingestellt sein koennte.
350 : :
351 : 0 : SwRect aClipRect;
352 [ # # ]: 0 : if ( rInf.OnWin() )
353 : : {
354 : 0 : aClipRect = SwRect( aOutPos, SvLSize() );
355 [ # # ]: 0 : aClipRect.Intersection( rInf.GetPaintRect() );
356 : : }
357 [ # # ]: 0 : SwSaveClip aClip( (OutputDevice*)rInf.GetOut() );
358 [ # # ]: 0 : aClip.ChgClip( aClipRect, rInf.GetTxtFrm() );
359 : : // Das machen, was man sonst nur macht ...
360 [ # # ]: 0 : PaintTxt( rInf );
361 : :
362 : : // Alte Werte sichern
363 : 0 : ((SwDropPortion*)this)->Height( nOldHeight );
364 : 0 : ((SwDropPortion*)this)->Width( nOldWidth );
365 : 0 : ((SwDropPortion*)this)->SetAscent( nOldAscent );
366 [ # # ]: 0 : ((SwTxtPaintInfo&)rInf).Y( nOldPosY );
367 : : }
368 : :
369 : : /*************************************************************************
370 : : * virtual SwDropPortion::Paint()
371 : : *************************************************************************/
372 : :
373 : 0 : void SwDropPortion::Paint( const SwTxtPaintInfo &rInf ) const
374 : : {
375 : : // ganz normale Ausgabe wird hier erledigt.
376 [ # # ][ # # ]: 0 : if( ! nDropHeight || ! pPart || 1 == nLines )
[ # # ]
377 : : {
378 [ # # # # : 0 : if ( rInf.OnWin() &&
# # ][ # # ]
[ # # ]
379 [ # # ]: 0 : !rInf.GetOpt().IsPagePreview() && !rInf.GetOpt().IsReadonly() && SwViewOption::IsFieldShadings() )
380 [ # # ]: 0 : rInf.DrawBackground( *this );
381 : :
382 : : // make sure that font is not rotated
383 : 0 : SwFont* pTmpFont = 0;
384 [ # # ][ # # ]: 0 : if ( rInf.GetFont()->GetOrientation( rInf.GetTxtFrm()->IsVertical() ) )
[ # # ]
385 : : {
386 [ # # ][ # # ]: 0 : pTmpFont = new SwFont( *rInf.GetFont() );
387 [ # # ][ # # ]: 0 : pTmpFont->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
388 : : }
389 : :
390 [ # # ]: 0 : SwFontSave aFontSave( rInf, pTmpFont );
391 : : // for text inside drop portions we let vcl handle the text directions
392 [ # # ]: 0 : SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
393 [ # # ]: 0 : aLayoutModeModifier.SetAuto();
394 : :
395 [ # # ]: 0 : SwTxtPortion::Paint( rInf );
396 [ # # ][ # # ]: 0 : delete pTmpFont;
[ # # ][ # # ]
397 : : }
398 : 0 : }
399 : :
400 : : /*************************************************************************
401 : : * virtual Format()
402 : : *************************************************************************/
403 : :
404 : :
405 : 0 : sal_Bool SwDropPortion::FormatTxt( SwTxtFormatInfo &rInf )
406 : : {
407 : 0 : const xub_StrLen nOldLen = GetLen();
408 : 0 : const xub_StrLen nOldInfLen = rInf.GetLen();
409 : 0 : const sal_Bool bFull = SwTxtPortion::Format( rInf );
410 [ # # ]: 0 : if( bFull )
411 : : {
412 : : // sieht zwar Scheisse aus, aber was soll man schon machen?
413 : 0 : rInf.SetUnderFlow( 0 );
414 : 0 : Truncate();
415 : 0 : SetLen( nOldLen );
416 : 0 : rInf.SetLen( nOldInfLen );
417 : : }
418 : 0 : return bFull;
419 : : }
420 : :
421 : : /*************************************************************************
422 : : * virtual GetTxtSize()
423 : : *************************************************************************/
424 : :
425 : :
426 : 0 : SwPosSize SwDropPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
427 : : {
428 : 0 : sal_uInt16 nMyX = 0;
429 : 0 : xub_StrLen nIdx = 0;
430 : :
431 : 0 : const SwDropPortionPart* pCurrPart = GetPart();
432 : :
433 : : // skip parts
434 [ # # ][ # # ]: 0 : while ( pCurrPart && nIdx + pCurrPart->GetLen() < rInf.GetLen() )
[ # # ]
435 : : {
436 : 0 : nMyX = nMyX + pCurrPart->GetWidth();
437 : 0 : nIdx = nIdx + pCurrPart->GetLen();
438 : 0 : pCurrPart = pCurrPart->GetFollow();
439 : : }
440 : :
441 : 0 : xub_StrLen nOldIdx = rInf.GetIdx();
442 : 0 : xub_StrLen nOldLen = rInf.GetLen();
443 : :
444 : 0 : ((SwTxtSizeInfo&)rInf).SetIdx( nIdx );
445 : 0 : ((SwTxtSizeInfo&)rInf).SetLen( rInf.GetLen() - nIdx );
446 : :
447 : : // robust
448 [ # # ][ # # ]: 0 : SwFontSave aFontSave( rInf, pCurrPart ? &pCurrPart->GetFont() : 0 );
449 [ # # ]: 0 : SwPosSize aPosSize( SwTxtPortion::GetTxtSize( rInf ) );
450 : 0 : aPosSize.Width( aPosSize.Width() + nMyX );
451 : :
452 : 0 : ((SwTxtSizeInfo&)rInf).SetIdx( nOldIdx );
453 : 0 : ((SwTxtSizeInfo&)rInf).SetLen( nOldLen );
454 : :
455 [ # # ]: 0 : return aPosSize;
456 : : }
457 : :
458 : : /*************************************************************************
459 : : * virtual GetCrsrOfst()
460 : : *************************************************************************/
461 : :
462 : 0 : xub_StrLen SwDropPortion::GetCrsrOfst( const KSHORT ) const
463 : : {
464 : 0 : return 0;
465 : : }
466 : :
467 : : /*************************************************************************
468 : : * SwTxtFormatter::CalcDropHeight()
469 : : *************************************************************************/
470 : :
471 : 0 : void SwTxtFormatter::CalcDropHeight( const MSHORT nLines )
472 : : {
473 : 0 : const SwLinePortion *const pOldCurr = GetCurr();
474 : 0 : KSHORT nDropHght = 0;
475 : 0 : KSHORT nAscent = 0;
476 : 0 : KSHORT nHeight = 0;
477 : 0 : KSHORT nDropLns = 0;
478 : 0 : sal_Bool bRegisterOld = IsRegisterOn();
479 : 0 : bRegisterOn = sal_False;
480 : :
481 [ # # ]: 0 : Top();
482 : :
483 [ # # ]: 0 : while( GetCurr()->IsDummy() )
484 : : {
485 [ # # ][ # # ]: 0 : if ( !Next() )
486 : 0 : break;
487 : : }
488 : :
489 : : // Wenn wir nur eine Zeile haben returnen wir 0
490 [ # # ][ # # ]: 0 : if( GetNext() || GetDropLines() == 1 )
[ # # ]
491 : : {
492 [ # # ]: 0 : for( ; nDropLns < nLines; nDropLns++ )
493 : : {
494 [ # # ]: 0 : if ( GetCurr()->IsDummy() )
495 : 0 : break;
496 : : else
497 : : {
498 [ # # ]: 0 : CalcAscentAndHeight( nAscent, nHeight );
499 : 0 : nDropHght = nDropHght + nHeight;
500 : 0 : bRegisterOn = bRegisterOld;
501 : : }
502 [ # # ][ # # ]: 0 : if ( !Next() )
503 : : {
504 : 0 : nDropLns++; // Fix: 11356
505 : 0 : break;
506 : : }
507 : : }
508 : :
509 : : // In der letzten Zeile plumpsen wir auf den Zeilenascent!
510 : 0 : nDropHght = nDropHght - nHeight;
511 : 0 : nDropHght = nDropHght + nAscent;
512 [ # # ]: 0 : Top();
513 : : }
514 : 0 : bRegisterOn = bRegisterOld;
515 : 0 : SetDropDescent( nHeight - nAscent );
516 : 0 : SetDropHeight( nDropHght );
517 : 0 : SetDropLines( nDropLns );
518 : : // Alte Stelle wiederfinden!
519 [ # # ]: 0 : while( pOldCurr != GetCurr() )
520 : : {
521 [ # # ][ # # ]: 0 : if( !Next() )
522 : : {
523 : : OSL_ENSURE( !this, "SwTxtFormatter::_CalcDropHeight: left Toulouse" );
524 : 0 : break;
525 : : }
526 : : }
527 : 0 : }
528 : :
529 : : /*************************************************************************
530 : : * SwTxtFormatter::GuessDropHeight()
531 : : *
532 : : * Wir schaetzen mal, dass die Fonthoehe sich nicht aendert und dass
533 : : * erst mindestens soviele Zeilen gibt, wie die DropCap-Einstellung angibt.
534 : : *
535 : : *************************************************************************/
536 : :
537 : :
538 : :
539 : 0 : void SwTxtFormatter::GuessDropHeight( const MSHORT nLines )
540 : : {
541 : : OSL_ENSURE( nLines, "GuessDropHeight: Give me more Lines!" );
542 : 0 : KSHORT nAscent = 0;
543 : 0 : KSHORT nHeight = 0;
544 : 0 : SetDropLines( nLines );
545 [ # # ]: 0 : if ( GetDropLines() > 1 )
546 : : {
547 [ # # ]: 0 : CalcRealHeight();
548 [ # # ]: 0 : CalcAscentAndHeight( nAscent, nHeight );
549 : : }
550 : 0 : SetDropDescent( nHeight - nAscent );
551 : 0 : SetDropHeight( nHeight * nLines - GetDropDescent() );
552 : 0 : }
553 : :
554 : : /*************************************************************************
555 : : * SwTxtFormatter::NewDropPortion
556 : : *************************************************************************/
557 : :
558 : 0 : SwDropPortion *SwTxtFormatter::NewDropPortion( SwTxtFormatInfo &rInf )
559 : : {
560 [ # # ]: 0 : if( !pDropFmt )
561 : 0 : return 0;
562 : :
563 [ # # ]: 0 : xub_StrLen nPorLen = pDropFmt->GetWholeWord() ? 0 : pDropFmt->GetChars();
564 : 0 : nPorLen = pFrm->GetTxtNode()->GetDropLen( nPorLen );
565 [ # # ]: 0 : if( !nPorLen )
566 : : {
567 : 0 : ((SwTxtFormatter*)this)->ClearDropFmt();
568 : 0 : return 0;
569 : : }
570 : :
571 : 0 : SwDropPortion *pDropPor = 0;
572 : :
573 : : // erste oder zweite Runde?
574 [ # # ][ # # ]: 0 : if ( !( GetDropHeight() || IsOnceMore() ) )
[ # # ]
575 : : {
576 [ # # ]: 0 : if ( GetNext() )
577 : 0 : CalcDropHeight( pDropFmt->GetLines() );
578 : : else
579 : 0 : GuessDropHeight( pDropFmt->GetLines() );
580 : : }
581 : :
582 : : // the DropPortion
583 [ # # ]: 0 : if( GetDropHeight() )
584 : 0 : pDropPor = new SwDropPortion( GetDropLines(), GetDropHeight(),
585 [ # # ]: 0 : GetDropDescent(), pDropFmt->GetDistance() );
586 : : else
587 [ # # ]: 0 : pDropPor = new SwDropPortion( 0,0,0,pDropFmt->GetDistance() );
588 : :
589 : 0 : pDropPor->SetLen( nPorLen );
590 : :
591 : : // If it was not possible to create a proper drop cap portion
592 : : // due to avoiding endless loops. We return a drop cap portion
593 : : // with an empty SwDropCapPart. For these portions the current
594 : : // font is used.
595 [ # # ]: 0 : if ( GetDropLines() < 2 )
596 : : {
597 : 0 : ((SwTxtFormatter*)this)->SetPaintDrop( sal_True );
598 : 0 : return pDropPor;
599 : : }
600 : :
601 : : // build DropPortionParts:
602 : : OSL_ENSURE( ! rInf.GetIdx(), "Drop Portion not at 0 position!" );
603 : 0 : xub_StrLen nNextChg = 0;
604 : 0 : const SwCharFmt* pFmt = pDropFmt->GetCharFmt();
605 : 0 : SwDropPortionPart* pCurrPart = 0;
606 : :
607 [ # # ]: 0 : while ( nNextChg < nPorLen )
608 : : {
609 : : // check for attribute changes and if the portion has to split:
610 : 0 : Seek( nNextChg );
611 : :
612 : : // the font is deleted in the destructor of the drop portion part
613 [ # # ]: 0 : SwFont* pTmpFnt = new SwFont( *rInf.GetFont() );
614 [ # # ]: 0 : if ( pFmt )
615 : : {
616 : 0 : const SwAttrSet& rSet = pFmt->GetAttrSet();
617 : 0 : pTmpFnt->SetDiffFnt( &rSet, pFrm->GetTxtNode()->getIDocumentSettingAccess() );
618 : : }
619 : :
620 : : // we do not allow a vertical font for the drop portion
621 : 0 : pTmpFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
622 : :
623 : : // find next attribute change / script change
624 : 0 : const xub_StrLen nTmpIdx = nNextChg;
625 : 0 : xub_StrLen nNextAttr = Min( GetNextAttr(), rInf.GetTxt().Len() );
626 : 0 : nNextChg = pScriptInfo->NextScriptChg( nTmpIdx );
627 [ # # ]: 0 : if( nNextChg > nNextAttr )
628 : 0 : nNextChg = nNextAttr;
629 [ # # ]: 0 : if ( nNextChg > nPorLen )
630 : 0 : nNextChg = nPorLen;
631 : :
632 : : SwDropPortionPart* pPart =
633 : 0 : new SwDropPortionPart( *pTmpFnt, nNextChg - nTmpIdx );
634 : :
635 [ # # ]: 0 : if ( ! pCurrPart )
636 : 0 : pDropPor->SetPart( pPart );
637 : : else
638 : 0 : pCurrPart->SetFollow( pPart );
639 : :
640 : 0 : pCurrPart = pPart;
641 : : }
642 : :
643 : 0 : ((SwTxtFormatter*)this)->SetPaintDrop( sal_True );
644 : 0 : return pDropPor;
645 : : }
646 : :
647 : : /*************************************************************************
648 : : * SwTxtPainter::PaintDropPortion()
649 : : *************************************************************************/
650 : :
651 : :
652 : :
653 : 0 : void SwTxtPainter::PaintDropPortion()
654 : : {
655 [ # # ]: 0 : const SwDropPortion *pDrop = GetInfo().GetParaPortion()->FindDropPortion();
656 : : OSL_ENSURE( pDrop, "DrapCop-Portion not available." );
657 [ # # ]: 0 : if( !pDrop )
658 : 0 : return;
659 : :
660 : 0 : const SwTwips nOldY = GetInfo().Y();
661 : :
662 [ # # ]: 0 : Top();
663 : :
664 : 0 : GetInfo().SetpSpaceAdd( pCurr->GetpLLSpaceAdd() );
665 : 0 : GetInfo().ResetSpaceIdx();
666 : 0 : GetInfo().SetKanaComp( pCurr->GetpKanaComp() );
667 : 0 : GetInfo().ResetKanaIdx();
668 : :
669 : : // 8047: Drops und Dummies
670 [ # # ][ # # ]: 0 : while( !pCurr->GetLen() && Next() )
[ # # ][ # # ]
671 : : ;
672 : :
673 : : // MarginPortion und Adjustment!
674 : 0 : const SwLinePortion *pPor = pCurr->GetFirstPortion();
675 : 0 : KSHORT nX = 0;
676 [ # # ][ # # ]: 0 : while( pPor && !pPor->IsDropPortion() )
[ # # ]
677 : : {
678 : 0 : nX = nX + pPor->Width();
679 : 0 : pPor = pPor->GetPortion();
680 : : }
681 [ # # ]: 0 : Point aLineOrigin( GetTopLeft() );
682 : :
683 : 0 : aLineOrigin.X() += nX;
684 : : KSHORT nTmpAscent, nTmpHeight;
685 [ # # ]: 0 : CalcAscentAndHeight( nTmpAscent, nTmpHeight );
686 : 0 : aLineOrigin.Y() += nTmpAscent;
687 : 0 : GetInfo().SetIdx( GetStart() );
688 : 0 : GetInfo().SetPos( aLineOrigin );
689 : 0 : GetInfo().SetLen( pDrop->GetLen() );
690 : :
691 [ # # ]: 0 : pDrop->PaintDrop( GetInfo() );
692 : :
693 : 0 : GetInfo().Y( nOldY );
694 : : }
695 : :
696 : : /*************************************************************************
697 : : * clas SwDropCapCache
698 : : *
699 : : * Da die Berechnung der Fontgroesse der Initialen ein teures Geschaeft ist,
700 : : * wird dies durch einen DropCapCache geschleust.
701 : : *************************************************************************/
702 : :
703 : : #define DROP_CACHE_SIZE 10
704 : :
705 : : class SwDropCapCache
706 : : {
707 : : long aMagicNo[ DROP_CACHE_SIZE ];
708 : : XubString aTxt[ DROP_CACHE_SIZE ];
709 : : sal_uInt16 aFactor[ DROP_CACHE_SIZE ];
710 : : KSHORT aWishedHeight[ DROP_CACHE_SIZE ];
711 : : short aDescent[ DROP_CACHE_SIZE ];
712 : : MSHORT nIndex;
713 : : public:
714 : : SwDropCapCache();
715 [ # # ][ # # ]: 0 : ~SwDropCapCache(){}
716 : : void CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf );
717 : : };
718 : :
719 : : /*************************************************************************
720 : : * SwDropCapCache Ctor / Dtor
721 : : *************************************************************************/
722 : :
723 [ # # ][ # # : 0 : SwDropCapCache::SwDropCapCache() : nIndex( 0 )
# # # # ]
724 : : {
725 : 0 : memset( &aMagicNo, 0, sizeof(aMagicNo) );
726 : 0 : memset( &aWishedHeight, 0, sizeof(aWishedHeight) );
727 : 0 : }
728 : :
729 : 73 : void SwDropPortion::DeleteDropCapCache()
730 : : {
731 [ - + ]: 73 : delete pDropCapCache;
732 : 73 : }
733 : :
734 : : /*************************************************************************
735 : : * SwDropCapCache::CalcFontSize
736 : : *************************************************************************/
737 : :
738 : 0 : void SwDropCapCache::CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf )
739 : : {
740 : 0 : const void* pFntNo = 0;
741 : 0 : MSHORT nTmpIdx = 0;
742 : :
743 : : OSL_ENSURE( pDrop->GetPart(),"DropPortion without part during font calculation");
744 : :
745 : 0 : SwDropPortionPart* pCurrPart = pDrop->GetPart();
746 : 0 : const sal_Bool bUseCache = ! pCurrPart->GetFollow();
747 : 0 : xub_StrLen nIdx = rInf.GetIdx();
748 [ # # ]: 0 : XubString aStr( rInf.GetTxt(), nIdx, pCurrPart->GetLen() );
749 : :
750 : 0 : long nAscent = 0;
751 : 0 : long nDescent = 0;
752 : 0 : long nFactor = -1;
753 : :
754 [ # # ]: 0 : if ( bUseCache )
755 : : {
756 : 0 : SwFont& rFnt = pCurrPart->GetFont();
757 [ # # ]: 0 : rFnt.ChkMagic( rInf.GetVsh(), rFnt.GetActual() );
758 : 0 : rFnt.GetMagic( pFntNo, nTmpIdx, rFnt.GetActual() );
759 : :
760 : 0 : nTmpIdx = 0;
761 : :
762 [ # # ][ # # ]: 0 : while( nTmpIdx < DROP_CACHE_SIZE &&
[ # # # # ]
[ # # ]
763 [ # # ]: 0 : ( aTxt[ nTmpIdx ] != aStr || aMagicNo[ nTmpIdx ] != long(pFntNo) ||
764 : 0 : aWishedHeight[ nTmpIdx ] != pDrop->GetDropHeight() ) )
765 : 0 : ++nTmpIdx;
766 : : }
767 : :
768 : : // we have to calculate a new font scaling factor if
769 : : // 1. we did not find a scaling factor in the cache or
770 : : // 2. we are not allowed to use the cache because the drop portion
771 : : // consists of more than one part
772 [ # # ][ # # ]: 0 : if( nTmpIdx >= DROP_CACHE_SIZE || ! bUseCache )
773 : : {
774 : 0 : ++nIndex;
775 : 0 : nIndex %= DROP_CACHE_SIZE;
776 : 0 : nTmpIdx = nIndex;
777 : :
778 : 0 : long nWishedHeight = pDrop->GetDropHeight();
779 : :
780 : : // find out biggest font size for initial scaling factor
781 : 0 : long nMaxFontHeight = 0;
782 [ # # ]: 0 : while ( pCurrPart )
783 : : {
784 : 0 : const SwFont& rFnt = pCurrPart->GetFont();
785 [ # # ]: 0 : const long nCurrHeight = rFnt.GetHeight( rFnt.GetActual() );
786 [ # # ]: 0 : if ( nCurrHeight > nMaxFontHeight )
787 : 0 : nMaxFontHeight = nCurrHeight;
788 : :
789 : 0 : pCurrPart = pCurrPart->GetFollow();
790 : : }
791 : :
792 : 0 : nFactor = ( 1000 * nWishedHeight ) / nMaxFontHeight;
793 : :
794 [ # # ]: 0 : if ( bUseCache )
795 : : {
796 : : // save keys for cache
797 : 0 : aMagicNo[ nTmpIdx ] = long(pFntNo);
798 [ # # ]: 0 : aTxt[ nTmpIdx ] = aStr;
799 : 0 : aWishedHeight[ nTmpIdx ] = KSHORT(nWishedHeight);
800 : : // save initial scaling factor
801 : 0 : aFactor[ nTmpIdx ] = (sal_uInt16)nFactor;
802 : : }
803 : :
804 : 0 : sal_Bool bGrow = ( pDrop->GetLen() != 0 );
805 : :
806 : : // for growing controll
807 : 0 : long nMax = KSHRT_MAX;
808 : 0 : long nMin = nFactor / 2;
809 : : #if OSL_DEBUG_LEVEL > 1
810 : : long nGrow = 0;
811 : : #endif
812 : :
813 : 0 : sal_Bool bWinUsed = sal_False;
814 [ # # ]: 0 : Font aOldFnt;
815 [ # # ]: 0 : MapMode aOldMap( MAP_TWIP );
816 : 0 : OutputDevice* pOut = rInf.GetOut();
817 : : OutputDevice* pWin;
818 [ # # ][ # # ]: 0 : if( rInf.GetVsh() && rInf.GetVsh()->GetWin() )
[ # # ]
819 : 0 : pWin = rInf.GetVsh()->GetWin();
820 : : else
821 [ # # ][ # # ]: 0 : pWin = GetpApp()->GetDefaultDevice();
822 : :
823 [ # # ]: 0 : while( bGrow )
824 : : {
825 : : // reset pCurrPart to first part
826 : 0 : pCurrPart = pDrop->GetPart();
827 : 0 : sal_Bool bFirstGlyphRect = sal_True;
828 : 0 : sal_Bool bHaveGlyphRect = sal_False;
829 [ # # ][ # # ]: 0 : Rectangle aCommonRect, aRect;
830 : :
831 [ # # ]: 0 : while ( pCurrPart )
832 : : {
833 : : // current font
834 : 0 : SwFont& rFnt = pCurrPart->GetFont();
835 : :
836 : : // Get height including proportion
837 : : const sal_uInt16 nCurrHeight =
838 [ # # ]: 0 : (sal_uInt16)rFnt.GetHeight( rFnt.GetActual() );
839 : :
840 : : // Get without proportion
841 : 0 : const sal_uInt8 nOldProp = rFnt.GetPropr();
842 [ # # ]: 0 : rFnt.SetProportion( 100 );
843 [ # # ]: 0 : Size aOldSize = Size( 0, rFnt.GetHeight( rFnt.GetActual() ) );
844 : :
845 : 0 : Size aNewSize( 0, ( nFactor * nCurrHeight ) / 1000 );
846 [ # # ]: 0 : rFnt.SetSize( aNewSize, rFnt.GetActual() );
847 [ # # ]: 0 : rFnt.ChgPhysFnt( rInf.GetVsh(), *pOut );
848 : :
849 [ # # ]: 0 : nAscent = rFnt.GetAscent( rInf.GetVsh(), *pOut );
850 : :
851 : : // Wir besorgen uns das alle Buchstaben umfassende Rechteck:
852 : 0 : bHaveGlyphRect = pOut->GetTextBoundRect( aRect, rInf.GetTxt(), 0,
853 [ # # ]: 0 : nIdx, pCurrPart->GetLen() ) &&
854 [ # # ][ # # ]: 0 : ! aRect.IsEmpty();
[ # # ]
855 : :
856 [ # # ]: 0 : if ( ! bHaveGlyphRect )
857 : : {
858 : : // getting glyph boundaries failed for some reason,
859 : : // we take the window for calculating sizes
860 [ # # ]: 0 : if ( pWin )
861 : : {
862 [ # # ]: 0 : if ( ! bWinUsed )
863 : : {
864 : 0 : bWinUsed = sal_True;
865 [ # # ]: 0 : aOldMap = pWin->GetMapMode( );
866 [ # # ][ # # ]: 0 : pWin->SetMapMode( MapMode( MAP_TWIP ) );
[ # # ]
867 [ # # ]: 0 : aOldFnt = pWin->GetFont();
868 : : }
869 [ # # ]: 0 : pWin->SetFont( rFnt.GetActualFont() );
870 : :
871 : 0 : bHaveGlyphRect = pWin->GetTextBoundRect( aRect, rInf.GetTxt(), 0,
872 [ # # ]: 0 : nIdx, pCurrPart->GetLen() ) &&
873 [ # # ][ # # ]: 0 : ! aRect.IsEmpty();
[ # # ]
874 : : }
875 [ # # ]: 0 : if ( bHaveGlyphRect )
876 : : {
877 [ # # ]: 0 : FontMetric aWinMet( pWin->GetFontMetric() );
878 [ # # ][ # # ]: 0 : nAscent = (KSHORT) aWinMet.GetAscent();
879 : : }
880 : : else
881 : : // We do not have a window or our window could not
882 : : // give us glyph boundaries.
883 [ # # ]: 0 : aRect = Rectangle( Point( 0, 0 ), Size( 0, nAscent ) );
884 : : }
885 : :
886 : : // Now we (hopefully) have a bounding rectangle for the
887 : : // glyphs of the current portion and the ascent of the current
888 : : // font
889 : :
890 : : // reset font size and proportion
891 [ # # ]: 0 : rFnt.SetSize( aOldSize, rFnt.GetActual() );
892 [ # # ]: 0 : rFnt.SetProportion( nOldProp );
893 : :
894 [ # # ]: 0 : if ( bFirstGlyphRect )
895 : : {
896 : 0 : aCommonRect = aRect;
897 : 0 : bFirstGlyphRect = sal_False;
898 : : }
899 : : else
900 [ # # ]: 0 : aCommonRect.Union( aRect );
901 : :
902 : 0 : nIdx = nIdx + pCurrPart->GetLen();
903 : 0 : pCurrPart = pCurrPart->GetFollow();
904 : : }
905 : :
906 : : // now we have a union ( aCommonRect ) of all glyphs with
907 : : // respect to a common baseline : 0
908 : :
909 : : // get descent and ascent from union
910 [ # # ][ # # ]: 0 : if ( rInf.GetTxtFrm()->IsVertical() )
911 : : {
912 : 0 : nDescent = aCommonRect.Left();
913 : 0 : nAscent = aCommonRect.Right();
914 : :
915 [ # # ]: 0 : if ( nDescent < 0 )
916 : 0 : nDescent = -nDescent;
917 : : }
918 : : else
919 : : {
920 : 0 : nDescent = aCommonRect.Bottom();
921 : 0 : nAscent = aCommonRect.Top();
922 : : }
923 [ # # ]: 0 : if ( nAscent < 0 )
924 : 0 : nAscent = -nAscent;
925 : :
926 : 0 : const long nHght = nAscent + nDescent;
927 [ # # ]: 0 : if ( nHght )
928 : : {
929 [ # # ]: 0 : if ( nHght > nWishedHeight )
930 : 0 : nMax = nFactor;
931 : : else
932 : : {
933 [ # # ]: 0 : if ( bUseCache )
934 : 0 : aFactor[ nTmpIdx ] = (sal_uInt16)nFactor;
935 : 0 : nMin = nFactor;
936 : : }
937 : :
938 : 0 : nFactor = ( nFactor * nWishedHeight ) / nHght;
939 [ # # ][ # # ]: 0 : bGrow = ( nFactor > nMin ) && ( nFactor < nMax );
940 : : #if OSL_DEBUG_LEVEL > 1
941 : : if ( bGrow )
942 : : nGrow++;
943 : : #endif
944 : 0 : nIdx = rInf.GetIdx();
945 : : }
946 : : else
947 : 0 : bGrow = sal_False;
948 : : }
949 : :
950 [ # # ]: 0 : if ( bWinUsed )
951 : : {
952 : : // reset window if it has been used
953 [ # # ]: 0 : pWin->SetMapMode( aOldMap );
954 [ # # ]: 0 : pWin->SetFont( aOldFnt );
955 : : }
956 : :
957 [ # # ]: 0 : if ( bUseCache )
958 [ # # ][ # # ]: 0 : aDescent[ nTmpIdx ] = -short( nDescent );
959 : : }
960 : :
961 : 0 : pCurrPart = pDrop->GetPart();
962 : :
963 : : // did made any new calculations or did we use the cache?
964 [ # # ]: 0 : if ( -1 == nFactor )
965 : : {
966 : 0 : nFactor = aFactor[ nTmpIdx ];
967 : 0 : nDescent = aDescent[ nTmpIdx ];
968 : : }
969 : : else
970 : 0 : nDescent = -nDescent;
971 : :
972 [ # # ]: 0 : while ( pCurrPart )
973 : : {
974 : : // scale current font
975 : 0 : SwFont& rFnt = pCurrPart->GetFont();
976 [ # # ]: 0 : Size aNewSize( 0, ( nFactor * rFnt.GetHeight( rFnt.GetActual() ) ) / 1000 );
977 : :
978 : 0 : const sal_uInt8 nOldProp = rFnt.GetPropr();
979 [ # # ]: 0 : rFnt.SetProportion( 100 );
980 [ # # ]: 0 : rFnt.SetSize( aNewSize, rFnt.GetActual() );
981 [ # # ]: 0 : rFnt.SetProportion( nOldProp );
982 : :
983 : 0 : pCurrPart = pCurrPart->GetFollow();
984 : : }
985 [ # # ]: 0 : pDrop->SetY( (short)nDescent );
986 : 0 : }
987 : :
988 : : /*************************************************************************
989 : : * virtual Format()
990 : : *************************************************************************/
991 : :
992 : 0 : sal_Bool SwDropPortion::Format( SwTxtFormatInfo &rInf )
993 : : {
994 : 0 : sal_Bool bFull = sal_False;
995 : 0 : Fix( (sal_uInt16)rInf.X() );
996 : :
997 [ # # ]: 0 : SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
998 [ # # ]: 0 : aLayoutModeModifier.SetAuto();
999 : :
1000 [ # # ][ # # ]: 0 : if( nDropHeight && pPart && nLines!=1 )
[ # # ]
1001 : : {
1002 [ # # ]: 0 : if( !pDropCapCache )
1003 [ # # ][ # # ]: 0 : pDropCapCache = new SwDropCapCache();
1004 : :
1005 : : // adjust font sizes to fit into the rectangle
1006 [ # # ]: 0 : pDropCapCache->CalcFontSize( this, rInf );
1007 : :
1008 : 0 : const long nOldX = rInf.X();
1009 : : {
1010 : 0 : SwDropSave aSave( rInf );
1011 : 0 : SwDropPortionPart* pCurrPart = pPart;
1012 : :
1013 [ # # ]: 0 : while ( pCurrPart )
1014 : : {
1015 : 0 : rInf.SetLen( pCurrPart->GetLen() );
1016 : 0 : SwFont& rFnt = pCurrPart->GetFont();
1017 : : {
1018 [ # # ]: 0 : SwFontSave aFontSave( rInf, &rFnt );
1019 [ # # ]: 0 : bFull = FormatTxt( rInf );
1020 : :
1021 [ # # ]: 0 : if ( bFull )
1022 [ # # ][ # # ]: 0 : break;
1023 : : }
1024 : :
1025 : : const SwTwips nTmpWidth =
1026 [ # # ][ # # ]: 0 : ( InSpaceGrp() && rInf.GetSpaceAdd() ) ?
1027 [ # # ][ # # ]: 0 : Width() + CalcSpacing( rInf.GetSpaceAdd(), rInf ) :
1028 [ # # ][ # # ]: 0 : Width();
1029 : :
1030 : : // set values
1031 : 0 : pCurrPart->SetWidth( (sal_uInt16)nTmpWidth );
1032 : :
1033 : : // Move
1034 : 0 : rInf.SetIdx( rInf.GetIdx() + pCurrPart->GetLen() );
1035 : 0 : rInf.X( rInf.X() + nTmpWidth );
1036 : 0 : pCurrPart = pCurrPart->GetFollow();
1037 : : }
1038 : :
1039 : 0 : Width( (sal_uInt16)(rInf.X() - nOldX) );
1040 : : }
1041 : :
1042 : : // reset my length
1043 : 0 : SetLen( rInf.GetLen() );
1044 : :
1045 : : // 7631, 7633: bei Ueberlappungen mit Flys ist Schluss.
1046 [ # # ]: 0 : if( ! bFull )
1047 [ # # ]: 0 : bFull = lcl_IsDropFlyInter( rInf, Width(), nDropHeight );
1048 : :
1049 [ # # ]: 0 : if( bFull )
1050 : : {
1051 : : // Durch FormatTxt kann nHeight auf 0 gesetzt worden sein
1052 [ # # ]: 0 : if ( !Height() )
1053 [ # # ]: 0 : Height( rInf.GetTxtHeight() );
1054 : :
1055 : : // Jetzt noch einmal der ganze Spass
1056 : 0 : nDropHeight = nLines = 0;
1057 [ # # ][ # # ]: 0 : delete pPart;
1058 : 0 : pPart = NULL;
1059 : :
1060 : : // meanwhile use normal formatting
1061 [ # # ]: 0 : bFull = SwTxtPortion::Format( rInf );
1062 : : }
1063 : : else
1064 : 0 : rInf.SetDropInit( sal_True );
1065 : :
1066 [ # # ]: 0 : Height( rInf.GetTxtHeight() );
1067 [ # # ]: 0 : SetAscent( rInf.GetAscent() );
1068 : : }
1069 : : else
1070 [ # # ]: 0 : bFull = SwTxtPortion::Format( rInf );
1071 : :
1072 [ # # ]: 0 : if( bFull )
1073 : 0 : nDistance = 0;
1074 : : else
1075 : : {
1076 : 0 : const KSHORT nWant = Width() + GetDistance();
1077 : 0 : const KSHORT nRest = (sal_uInt16)(rInf.Width() - rInf.X());
1078 [ # # ][ # # ]: 0 : if( ( nWant > nRest ) ||
[ # # ]
1079 [ # # ]: 0 : lcl_IsDropFlyInter( rInf, Width() + GetDistance(), nDropHeight ) )
1080 : 0 : nDistance = 0;
1081 : :
1082 : 0 : Width( Width() + nDistance );
1083 : : }
1084 [ # # ]: 0 : return bFull;
1085 : : }
1086 : :
1087 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|