1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include <hintids.hxx>
27 #include <sfx2/printer.hxx>
28 #include <editeng/lspcitem.hxx>
29 #include <editeng/adjitem.hxx>
30 #include <editeng/escpitem.hxx>
31 #include <editeng/lrspitem.hxx>
32 #include <editeng/pgrditem.hxx>
33 #include <vcl/window.hxx>
34 #include <vcl/svapp.hxx>
35 #include <viewsh.hxx> // ViewShell
36 #include <viewopt.hxx>
37 #include <ndtxt.hxx> // SwTxtNode
38 #include <pagefrm.hxx> // SwPageFrm
39 #include <paratr.hxx>
40 #include <SwPortionHandler.hxx>
41 #include <txtcfg.hxx>
42 #include <porrst.hxx>
43 #include <inftxt.hxx>
44 #include <txtpaint.hxx> // ClipVout
45 #include <swfntcch.hxx> // SwFontAccess
46 #include <tgrditem.hxx>
47 #include <pagedesc.hxx> // SwPageDesc
48 #include <frmatr.hxx>
49 #include <redlnitr.hxx> // SwRedlineItr
50 #include <porfly.hxx> // SwFlyPortion
51 #include <atrhndl.hxx>
52 #include "rootfrm.hxx"
53
54 #include <IDocumentRedlineAccess.hxx>
55 #include <IDocumentSettingAccess.hxx>
56 #include <IDocumentDeviceAccess.hxx>
57
58 /*************************************************************************
59 * class SwTmpEndPortion
60 *************************************************************************/
61
SwTmpEndPortion(const SwLinePortion & rPortion)62 SwTmpEndPortion::SwTmpEndPortion( const SwLinePortion &rPortion )
63 {
64 Height( rPortion.Height() );
65 SetAscent( rPortion.GetAscent() );
66 SetWhichPor( POR_TMPEND );
67 }
68
69 /*************************************************************************
70 * virtual SwTmpEndPortion::Paint()
71 *************************************************************************/
72
Paint(const SwTxtPaintInfo & rInf) const73 void SwTmpEndPortion::Paint( const SwTxtPaintInfo &rInf ) const
74 {
75 if( rInf.OnWin() && rInf.GetOpt().IsParagraph() )
76 {
77 SwDefFontSave aSave( rInf );
78 const XubString aTmp( CH_PAR );
79 rInf.DrawText( aTmp, *this );
80 }
81 }
82
83 /*************************************************************************
84 * class SwBreakPortion
85 *************************************************************************/
SwBreakPortion(const SwLinePortion & rPortion)86 SwBreakPortion::SwBreakPortion( const SwLinePortion &rPortion )
87 : SwLinePortion( rPortion )
88 {
89 nLineLength = 1;
90 SetWhichPor( POR_BRK );
91 }
92
GetCrsrOfst(const KSHORT) const93 xub_StrLen SwBreakPortion::GetCrsrOfst( const KSHORT ) const
94 { return 0; }
95
GetViewWidth(const SwTxtSizeInfo &) const96 KSHORT SwBreakPortion::GetViewWidth( const SwTxtSizeInfo & ) const
97 { return 0; }
98
Compress()99 SwLinePortion *SwBreakPortion::Compress()
100 { return (GetPortion() && GetPortion()->InTxtGrp() ? 0 : this); }
101
Paint(const SwTxtPaintInfo & rInf) const102 void SwBreakPortion::Paint( const SwTxtPaintInfo &rInf ) const
103 {
104 if( rInf.OnWin() && rInf.GetOpt().IsLineBreak() )
105 rInf.DrawLineBreak( *this );
106 }
107
108 /*************************************************************************
109 * virtual SwBreakPortion::Format()
110 *************************************************************************/
111
Format(SwTxtFormatInfo & rInf)112 sal_Bool SwBreakPortion::Format( SwTxtFormatInfo &rInf )
113 {
114 const SwLinePortion *pRoot = rInf.GetRoot();
115 Width( 0 );
116 Height( pRoot->Height() );
117 SetAscent( pRoot->GetAscent() );
118 if ( rInf.GetIdx()+1 == rInf.GetTxt().Len() )
119 rInf.SetNewLine( sal_True );
120 return sal_True;
121 }
122
123 /*************************************************************************
124 * virtual SwBreakPortion::HandlePortion()
125 *************************************************************************/
126
HandlePortion(SwPortionHandler & rPH) const127 void SwBreakPortion::HandlePortion( SwPortionHandler& rPH ) const
128 {
129 rPH.Text( GetLen(), GetWhichPor() );
130 }
131
132
SwKernPortion(SwLinePortion & rPortion,short nKrn,sal_Bool bBG,sal_Bool bGK)133 SwKernPortion::SwKernPortion( SwLinePortion &rPortion, short nKrn,
134 sal_Bool bBG, sal_Bool bGK ) :
135 nKern( nKrn ), bBackground( bBG ), bGridKern( bGK )
136 {
137 Height( rPortion.Height() );
138 SetAscent( rPortion.GetAscent() );
139 nLineLength = 0;
140 SetWhichPor( POR_KERN );
141 if( nKern > 0 )
142 Width( nKern );
143 rPortion.Insert( this );
144 }
145
SwKernPortion(const SwLinePortion & rPortion)146 SwKernPortion::SwKernPortion( const SwLinePortion& rPortion ) :
147 nKern( 0 ), bBackground( sal_False ), bGridKern( sal_True )
148 {
149 Height( rPortion.Height() );
150 SetAscent( rPortion.GetAscent() );
151
152 nLineLength = 0;
153 SetWhichPor( POR_KERN );
154 }
155
Paint(const SwTxtPaintInfo & rInf) const156 void SwKernPortion::Paint( const SwTxtPaintInfo &rInf ) const
157 {
158 if( Width() )
159 {
160 // bBackground is set for Kerning Portions between two fields
161 if ( bBackground )
162 rInf.DrawViewOpt( *this, POR_FLD );
163
164 rInf.DrawBackBrush( *this );
165
166 // do we have to repaint a post it portion?
167 if( rInf.OnWin() && pPortion && !pPortion->Width() )
168 pPortion->PrePaint( rInf, this );
169
170 if( rInf.GetFont()->IsPaintBlank() )
171 {
172 static sal_Char __READONLY_DATA sDoubleSpace[] = " ";
173 XubString aTxtDouble( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
174 // --> FME 2006-07-12 #b6439097#
175 SwRect aClipRect;
176 rInf.CalcRect( *this, &aClipRect, 0 );
177 SwSaveClip aClip( (OutputDevice*)rInf.GetOut() );
178 aClip.ChgClip( aClipRect, 0 );
179 // <--
180 rInf.DrawText( aTxtDouble, *this, 0, 2, sal_True );
181 }
182 }
183 }
184
FormatEOL(SwTxtFormatInfo & rInf)185 void SwKernPortion::FormatEOL( SwTxtFormatInfo &rInf )
186 {
187 if ( bGridKern )
188 return;
189
190 if( rInf.GetLast() == this )
191 rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
192 if( nKern < 0 )
193 Width( -nKern );
194 else
195 Width( 0 );
196 rInf.GetLast()->FormatEOL( rInf );
197 }
198
SwArrowPortion(const SwLinePortion & rPortion)199 SwArrowPortion::SwArrowPortion( const SwLinePortion &rPortion ) :
200 bLeft( sal_True )
201 {
202 Height( rPortion.Height() );
203 SetAscent( rPortion.GetAscent() );
204 nLineLength = 0;
205 SetWhichPor( POR_ARROW );
206 }
207
SwArrowPortion(const SwTxtPaintInfo & rInf)208 SwArrowPortion::SwArrowPortion( const SwTxtPaintInfo &rInf )
209 : bLeft( sal_False )
210 {
211 Height( (sal_uInt16)(rInf.GetTxtFrm()->Prt().Height()) );
212 aPos.X() = rInf.GetTxtFrm()->Frm().Left() +
213 rInf.GetTxtFrm()->Prt().Right();
214 aPos.Y() = rInf.GetTxtFrm()->Frm().Top() +
215 rInf.GetTxtFrm()->Prt().Bottom();
216 SetWhichPor( POR_ARROW );
217 }
218
Paint(const SwTxtPaintInfo & rInf) const219 void SwArrowPortion::Paint( const SwTxtPaintInfo &rInf ) const
220 {
221 ((SwArrowPortion*)this)->aPos = rInf.GetPos();
222 }
223
Compress()224 SwLinePortion *SwArrowPortion::Compress() { return this; }
225
EmptyHeight() const226 SwTwips SwTxtFrm::EmptyHeight() const
227 {
228 ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::EmptyHeight with swapped frame" );
229
230 SwFont *pFnt;
231 const SwTxtNode& rTxtNode = *GetTxtNode();
232 const IDocumentSettingAccess* pIDSA = rTxtNode.getIDocumentSettingAccess();
233 ViewShell *pSh = getRootFrm()->GetCurrShell();
234 if ( rTxtNode.HasSwAttrSet() )
235 {
236 const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() );
237 pFnt = new SwFont( pAttrSet, pIDSA );
238 }
239 else
240 {
241 SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh);
242 pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
243 pFnt->ChkMagic( pSh, pFnt->GetActual() );
244 }
245
246 if ( IsVertical() )
247 pFnt->SetVertical( 2700 );
248
249 OutputDevice* pOut = pSh ? pSh->GetOut() : 0;
250 if ( !pOut || !pSh->GetViewOptions()->getBrowseMode() ||
251 pSh->GetViewOptions()->IsPrtFormat() )
252 {
253 pOut = rTxtNode.getIDocumentDeviceAccess()->getReferenceDevice(true);
254 }
255
256 const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess();
257 if( IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) )
258 {
259 MSHORT nRedlPos = pIDRA->GetRedlinePos( rTxtNode, USHRT_MAX );
260 if( MSHRT_MAX != nRedlPos )
261 {
262 SwAttrHandler aAttrHandler;
263 aAttrHandler.Init( GetTxtNode()->GetSwAttrSet(),
264 *GetTxtNode()->getIDocumentSettingAccess(), NULL );
265 SwRedlineItr aRedln( rTxtNode, *pFnt, aAttrHandler,
266 nRedlPos, sal_True );
267 }
268 }
269
270 SwTwips nRet;
271 if( !pOut )
272 nRet = IsVertical() ?
273 Prt().SSize().Width() + 1 :
274 Prt().SSize().Height() + 1;
275 else
276 {
277 pFnt->SetFntChg( sal_True );
278 pFnt->ChgPhysFnt( pSh, *pOut );
279 nRet = pFnt->GetHeight( pSh, *pOut );
280 }
281 delete pFnt;
282 return nRet;
283 }
284
285 /*************************************************************************
286 * SwTxtFrm::FormatEmpty()
287 *************************************************************************/
288
FormatEmpty()289 sal_Bool SwTxtFrm::FormatEmpty()
290 {
291 ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::FormatEmpty with swapped frame" );
292
293 if ( HasFollow() || GetTxtNode()->GetpSwpHints() ||
294 0 != GetTxtNode()->GetNumRule() ||
295 GetTxtNode()->HasHiddenCharAttribute( true ) ||
296 IsInFtn() || ( HasPara() && GetPara()->IsPrepMustFit() ) )
297 return sal_False;
298 const SwAttrSet& aSet = GetTxtNode()->GetSwAttrSet();
299 const SvxAdjust nAdjust = aSet.GetAdjust().GetAdjust();
300 if( ( ( ! IsRightToLeft() && ( SVX_ADJUST_LEFT != nAdjust ) ) ||
301 ( IsRightToLeft() && ( SVX_ADJUST_RIGHT != nAdjust ) ) ) ||
302 aSet.GetRegister().GetValue() )
303 return sal_False;
304 const SvxLineSpacingItem &rSpacing = aSet.GetLineSpacing();
305 if( SVX_LINE_SPACE_MIN == rSpacing.GetLineSpaceRule() ||
306 SVX_LINE_SPACE_FIX == rSpacing.GetLineSpaceRule() ||
307 aSet.GetLRSpace().IsAutoFirst() )
308 return sal_False;
309 else
310 {
311 SwTxtFly aTxtFly( this );
312 SwRect aRect;
313 sal_Bool bFirstFlyCheck = 0 != Prt().Height();
314 if ( bFirstFlyCheck &&
315 aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
316 return sal_False;
317 else
318 {
319 SwTwips nHeight = EmptyHeight();
320
321 if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() &&
322 IsInDocBody() )
323 {
324 GETGRID( FindPageFrm() )
325 if ( pGrid )
326 nHeight = pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
327 }
328
329 SWRECTFN( this )
330 const SwTwips nChg = nHeight - (Prt().*fnRect->fnGetHeight)();
331
332 if( !nChg )
333 SetUndersized( sal_False );
334 AdjustFrm( nChg );
335
336 if( HasBlinkPor() )
337 {
338 ClearPara();
339 ResetBlinkPor();
340 }
341 SetCacheIdx( MSHRT_MAX );
342 if( !IsEmpty() )
343 {
344 SetEmpty( sal_True );
345 SetCompletePaint();
346 }
347 if( !bFirstFlyCheck &&
348 aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
349 return sal_False;
350
351 // --> OD 2004-11-17 #i35635# - call method <HideAndShowObjects()>
352 // to assure that objects anchored at the empty paragraph are
353 // correctly visible resp. invisible.
354 HideAndShowObjects();
355 // <--
356 return sal_True;
357 }
358 }
359 }
360
FillRegister(SwTwips & rRegStart,KSHORT & rRegDiff)361 sal_Bool SwTxtFrm::FillRegister( SwTwips& rRegStart, KSHORT& rRegDiff )
362 {
363 const SwFrm *pFrm = this;
364 rRegDiff = 0;
365 while( !( ( FRM_BODY | FRM_FLY )
366 & pFrm->GetType() ) && pFrm->GetUpper() )
367 pFrm = pFrm->GetUpper();
368 if( ( FRM_BODY| FRM_FLY ) & pFrm->GetType() )
369 {
370 SWRECTFN( pFrm )
371 rRegStart = (pFrm->*fnRect->fnGetPrtTop)();
372 pFrm = pFrm->FindPageFrm();
373 if( pFrm->IsPageFrm() )
374 {
375 SwPageDesc* pDesc = ((SwPageFrm*)pFrm)->FindPageDesc();
376 if( pDesc )
377 {
378 rRegDiff = pDesc->GetRegHeight();
379 if( !rRegDiff )
380 {
381 const SwTxtFmtColl *pFmt = pDesc->GetRegisterFmtColl();
382 if( pFmt )
383 {
384 const SvxLineSpacingItem &rSpace = pFmt->GetLineSpacing();
385 if( SVX_LINE_SPACE_FIX == rSpace.GetLineSpaceRule() )
386 {
387 rRegDiff = rSpace.GetLineHeight();
388 pDesc->SetRegHeight( rRegDiff );
389 pDesc->SetRegAscent( ( 4 * rRegDiff ) / 5 );
390 }
391 else
392 {
393 ViewShell *pSh = getRootFrm()->GetCurrShell();
394 SwFontAccess aFontAccess( pFmt, pSh );
395 SwFont aFnt( *aFontAccess.Get()->GetFont() );
396
397 OutputDevice *pOut = 0;
398 if( !pSh || !pSh->GetViewOptions()->getBrowseMode() ||
399 pSh->GetViewOptions()->IsPrtFormat() )
400 pOut = GetTxtNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
401
402 if( pSh && !pOut )
403 pOut = pSh->GetWin();
404
405 if( !pOut )
406 pOut = GetpApp()->GetDefaultDevice();
407
408 MapMode aOldMap( pOut->GetMapMode() );
409 pOut->SetMapMode( MapMode( MAP_TWIP ) );
410
411 aFnt.ChgFnt( pSh, *pOut );
412 rRegDiff = aFnt.GetHeight( pSh, *pOut );
413 KSHORT nNettoHeight = rRegDiff;
414
415 switch( rSpace.GetLineSpaceRule() )
416 {
417 case SVX_LINE_SPACE_AUTO:
418 break;
419 case SVX_LINE_SPACE_MIN:
420 {
421 if( rRegDiff < KSHORT( rSpace.GetLineHeight() ) )
422 rRegDiff = rSpace.GetLineHeight();
423 break;
424 }
425 default: ASSERT(
426 sal_False, ": unknown LineSpaceRule" );
427 }
428 switch( rSpace.GetInterLineSpaceRule() )
429 {
430 case SVX_INTER_LINE_SPACE_OFF:
431 break;
432 case SVX_INTER_LINE_SPACE_PROP:
433 {
434 long nTmp = rSpace.GetPropLineSpace();
435 if( nTmp < 50 )
436 nTmp = nTmp ? 50 : 100;
437 nTmp *= rRegDiff;
438 nTmp /= 100;
439 if( !nTmp )
440 ++nTmp;
441 rRegDiff = (KSHORT)nTmp;
442 nNettoHeight = rRegDiff;
443 break;
444 }
445 case SVX_INTER_LINE_SPACE_FIX:
446 {
447 rRegDiff = rRegDiff + rSpace.GetInterLineSpace();
448 nNettoHeight = rRegDiff;
449 break;
450 }
451 default: ASSERT( sal_False, ": unknown InterLineSpaceRule" );
452 }
453 pDesc->SetRegHeight( rRegDiff );
454 pDesc->SetRegAscent( rRegDiff - nNettoHeight +
455 aFnt.GetAscent( pSh, *pOut ) );
456 pOut->SetMapMode( aOldMap );
457 }
458 }
459 }
460 const long nTmpDiff = pDesc->GetRegAscent() - rRegDiff;
461 if ( bVert )
462 rRegStart -= nTmpDiff;
463 else
464 rRegStart += nTmpDiff;
465 }
466 }
467 }
468 return ( 0 != rRegDiff );
469 }
470
471 /*************************************************************************
472 * virtual SwHiddenTextPortion::Paint()
473 *************************************************************************/
474
Paint(const SwTxtPaintInfo & rInf) const475 void SwHiddenTextPortion::Paint( const SwTxtPaintInfo & rInf) const
476 {
477 (void)rInf;
478 #if OSL_DEBUG_LEVEL > 1
479 OutputDevice* pOut = (OutputDevice*)rInf.GetOut();
480 Color aCol( SwViewOption::GetFieldShadingsColor() );
481 Color aOldColor( pOut->GetFillColor() );
482 pOut->SetFillColor( aCol );
483 Point aPos( rInf.GetPos() );
484 aPos.Y() -= 150;
485 aPos.X() -= 25;
486 SwRect aRect( aPos, Size( 100, 200 ) );
487 ((OutputDevice*)pOut)->DrawRect( aRect.SVRect() );
488 pOut->SetFillColor( aOldColor );
489 #endif
490 }
491
492 /*************************************************************************
493 * virtual SwHiddenTextPortion::Format()
494 *************************************************************************/
495
Format(SwTxtFormatInfo & rInf)496 sal_Bool SwHiddenTextPortion::Format( SwTxtFormatInfo &rInf )
497 {
498 Width( 0 );
499 rInf.GetTxtFrm()->HideFootnotes( rInf.GetIdx(), rInf.GetIdx() + GetLen() );
500
501 return sal_False;
502 };
503
504 /*************************************************************************
505 * virtual SwControlCharPortion::Paint()
506 *************************************************************************/
507
Paint(const SwTxtPaintInfo & rInf) const508 void SwControlCharPortion::Paint( const SwTxtPaintInfo &rInf ) const
509 {
510 if ( Width() ) // is only set during prepaint mode
511 {
512 rInf.DrawViewOpt( *this, POR_CONTROLCHAR );
513
514 if ( !rInf.GetOpt().IsPagePreview() &&
515 !rInf.GetOpt().IsReadonly() &&
516 SwViewOption::IsFieldShadings() &&
517 CHAR_ZWNBSP != mcChar )
518 {
519 SwFont aTmpFont( *rInf.GetFont() );
520 aTmpFont.SetEscapement( CHAR_ZWSP == mcChar ? DFLT_ESC_AUTO_SUB : -25 );
521 const sal_uInt16 nProp = 40;
522 aTmpFont.SetProportion( nProp ); // a smaller font
523 SwFontSave aFontSave( rInf, &aTmpFont );
524
525 String aOutString;
526
527 switch ( mcChar )
528 {
529 case CHAR_ZWSP :
530 aOutString = '/'; break;
531 // case CHAR_LRM :
532 // rTxt = sal_Unicode(0x2514); break;
533 // case CHAR_RLM :
534 // rTxt = sal_Unicode(0x2518); break;
535 }
536
537 if ( !mnHalfCharWidth )
538 mnHalfCharWidth = rInf.GetTxtSize( aOutString ).Width() / 2;
539
540 Point aOldPos = rInf.GetPos();
541 Point aNewPos( aOldPos );
542 aNewPos.X() = aNewPos.X() + ( Width() / 2 ) - mnHalfCharWidth;
543 const_cast< SwTxtPaintInfo& >( rInf ).SetPos( aNewPos );
544
545 rInf.DrawText( aOutString, *this );
546
547 const_cast< SwTxtPaintInfo& >( rInf ).SetPos( aOldPos );
548 }
549 }
550 }
551
552 /*************************************************************************
553 * virtual SwControlCharPortion::Format()
554 *************************************************************************/
555
Format(SwTxtFormatInfo & rInf)556 sal_Bool SwControlCharPortion::Format( SwTxtFormatInfo &rInf )
557 {
558 const SwLinePortion* pRoot = rInf.GetRoot();
559 Width( 0 );
560 Height( pRoot->Height() );
561 SetAscent( pRoot->GetAscent() );
562
563 return sal_False;
564 }
565
566 /*************************************************************************
567 * virtual SwControlCharPortion::GetViewWidth()
568 *************************************************************************/
569
GetViewWidth(const SwTxtSizeInfo & rInf) const570 KSHORT SwControlCharPortion::GetViewWidth( const SwTxtSizeInfo& rInf ) const
571 {
572 if( !mnViewWidth )
573 mnViewWidth = rInf.GetTxtSize( ' ' ).Width();
574
575 return mnViewWidth;
576 }
577