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 : :
30 : : #include <com/sun/star/text/HoriOrientation.hpp>
31 : : #include <hintids.hxx>
32 : : #include <tools/shl.hxx> // SW_MOD
33 : : #include <editeng/pgrditem.hxx>
34 : : #include <editeng/lrspitem.hxx>
35 : : #include <pagedesc.hxx> // SwPageDesc
36 : : #include <tgrditem.hxx>
37 : : #include <paratr.hxx>
38 : :
39 : : #include <fmtline.hxx>
40 : : #include <lineinfo.hxx>
41 : : #include <charfmt.hxx>
42 : : #include "rootfrm.hxx"
43 : : #include <pagefrm.hxx>
44 : : #include <viewsh.hxx> // ViewShell
45 : : #include <viewimp.hxx> // SwViewImp
46 : : #include <viewopt.hxx> // SwViewOption
47 : : #include <frmtool.hxx> // DrawGraphic
48 : : #include <txtfrm.hxx> // SwTxtFrm
49 : : #include <itrpaint.hxx> // SwTxtPainter
50 : : #include <txtpaint.hxx> // SwSaveClip
51 : : #include <txtcache.hxx> // SwTxtLineAccess
52 : : #include <flyfrm.hxx> // SwFlyFrm
53 : : #include <redlnitr.hxx> // SwRedlineItr
54 : : #include <swmodule.hxx> // SW_MOD
55 : : #include <tabfrm.hxx> // SwTabFrm (Redlining)
56 : : #include <SwGrammarMarkUp.hxx>
57 : :
58 : : // #i12836# enhanced pdf export
59 : : #include <EnhancedPDFExportHelper.hxx>
60 : :
61 : : #include <IDocumentStylePoolAccess.hxx>
62 : : #include <IDocumentLineNumberAccess.hxx>
63 : :
64 : : // variable moved to class <numfunc:GetDefBulletConfig>
65 : : //extern const sal_Char sBulletFntName[];
66 : : namespace numfunc
67 : : {
68 : : extern const String& GetDefBulletFontname();
69 : : extern bool IsDefBulletFontUserDefined();
70 : : }
71 : :
72 : :
73 : : #define REDLINE_DISTANCE 567/4
74 : : #define REDLINE_MINDIST 567/10
75 : :
76 : : using namespace ::com::sun::star;
77 : :
78 : : ////////////////////////////////////////////////////////////
79 : :
80 : : sal_Bool bInitFont = sal_True;
81 : :
82 : : class SwExtraPainter
83 : : {
84 : : SwSaveClip aClip;
85 : : SwRect aRect;
86 : : const SwTxtFrm* pTxtFrm;
87 : : ViewShell *pSh;
88 : : SwFont* pFnt;
89 : : const SwLineNumberInfo &rLineInf;
90 : : SwTwips nX;
91 : : SwTwips nRedX;
92 : : sal_uLong nLineNr;
93 : : MSHORT nDivider;
94 : : sal_Bool bGoLeft;
95 : : sal_Bool bLineNum;
96 : 6 : inline sal_Bool IsClipChg() { return aClip.IsChg(); }
97 : : public:
98 : : SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh,
99 : : const SwLineNumberInfo &rLnInf, const SwRect &rRct,
100 : : sal_Int16 eHor, sal_Bool bLnNm );
101 [ + - ][ + - ]: 32 : ~SwExtraPainter() { delete pFnt; }
102 : 6 : inline SwFont* GetFont() const { return pFnt; }
103 : 26 : inline void IncLineNr() { ++nLineNr; }
104 : 36 : inline sal_Bool HasNumber() { return !( nLineNr % rLineInf.GetCountBy() ); }
105 [ + - ]: 24 : inline sal_Bool HasDivider() { if( !nDivider ) return sal_False;
106 : 24 : return !(nLineNr % rLineInf.GetDividerCountBy()); }
107 : :
108 : : void PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed );
109 : : void PaintRedline( SwTwips nY, long nMax );
110 : : };
111 : :
112 : :
113 : 32 : SwExtraPainter::SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh,
114 : : const SwLineNumberInfo &rLnInf, const SwRect &rRct,
115 : : sal_Int16 eHor, sal_Bool bLnNm )
116 : 32 : : aClip( pVwSh->GetWin() || pFrm->IsUndersized() ? pVwSh->GetOut() : 0 ),
117 : : aRect( rRct ), pTxtFrm( pFrm ), pSh( pVwSh ), pFnt( 0 ), rLineInf( rLnInf ),
118 [ - + # # ]: 32 : nLineNr( 1L ), bLineNum( bLnNm )
119 : : {
120 [ - + ]: 32 : if( pFrm->IsUndersized() )
121 : : {
122 : 0 : SwTwips nBottom = pFrm->Frm().Bottom();
123 [ # # ]: 0 : if( aRect.Bottom() > nBottom )
124 : 0 : aRect.Bottom( nBottom );
125 : : }
126 : 32 : MSHORT nVirtPageNum = 0;
127 [ + - ]: 32 : if( bLineNum )
128 : : {/* Initializes the Members necessary for line numbering:
129 : :
130 : : nDivider, how often do we want a substring; 0 == never
131 : : nX, line number's x position
132 : : pFnt, line number's font
133 : : nLineNr, the first line number
134 : : bLineNum is set back to sal_False if the numbering is completely
135 : : outside of the paint rect */
136 [ - + ]: 32 : nDivider = rLineInf.GetDivider().Len() ? rLineInf.GetDividerCountBy() : 0;
137 : 32 : nX = pFrm->Frm().Left();
138 [ + - ][ + - ]: 32 : SwCharFmt* pFmt = rLineInf.GetCharFmt( const_cast<IDocumentStylePoolAccess&>(*pFrm->GetNode()->getIDocumentStylePoolAccess()) );
139 : : OSL_ENSURE( pFmt, "PaintExtraData without CharFmt" );
140 [ + - ][ + - ]: 32 : pFnt = new SwFont( &pFmt->GetAttrSet(), pFrm->GetTxtNode()->getIDocumentSettingAccess() );
[ + - ]
141 : 32 : pFnt->Invalidate();
142 [ + - ]: 32 : pFnt->ChgPhysFnt( pSh, *pSh->GetOut() );
143 [ + - ][ + - ]: 32 : pFnt->SetVertical( 0, pFrm->IsVertical() );
144 : 32 : nLineNr += pFrm->GetAllLines() - pFrm->GetThisLines();
145 : 32 : LineNumberPosition ePos = rLineInf.GetPos();
146 [ # # ][ - + ]: 32 : if( ePos != LINENUMBER_POS_LEFT && ePos != LINENUMBER_POS_RIGHT )
147 : : {
148 [ # # ][ # # ]: 0 : if( pFrm->FindPageFrm()->OnRightPage() )
[ # # ]
149 : : {
150 : 0 : nVirtPageNum = 1;
151 : : ePos = ePos == LINENUMBER_POS_INSIDE ?
152 : 0 : LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT;
153 : : }
154 : : else
155 : : {
156 : 0 : nVirtPageNum = 2;
157 : : ePos = ePos == LINENUMBER_POS_OUTSIDE ?
158 : 0 : LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT;
159 : : }
160 : : }
161 [ + - ]: 32 : if( LINENUMBER_POS_LEFT == ePos )
162 : : {
163 : 32 : bGoLeft = sal_True;
164 : 32 : nX -= rLineInf.GetPosFromLeft();
165 [ + + ]: 32 : if( nX < aRect.Left() )
166 : 12 : bLineNum = sal_False;
167 : : }
168 : : else
169 : : {
170 : 0 : bGoLeft = sal_False;
171 : 0 : nX += pFrm->Frm().Width() + rLineInf.GetPosFromLeft();
172 [ # # ]: 0 : if( nX > aRect.Right() )
173 : 0 : bLineNum = sal_False;
174 : : }
175 : : }
176 [ + - ]: 32 : if( eHor != text::HoriOrientation::NONE )
177 : : {
178 [ + - ][ - + ]: 32 : if( text::HoriOrientation::INSIDE == eHor || text::HoriOrientation::OUTSIDE == eHor )
179 : : {
180 [ # # ]: 0 : if( !nVirtPageNum )
181 [ # # ][ # # ]: 0 : nVirtPageNum = pFrm->FindPageFrm()->OnRightPage() ? 1 : 2;
[ # # ]
182 [ # # ]: 0 : if( nVirtPageNum % 2 )
183 [ # # ]: 0 : eHor = eHor == text::HoriOrientation::INSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT;
184 : : else
185 [ # # ]: 0 : eHor = eHor == text::HoriOrientation::OUTSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT;
186 : : }
187 [ + - ]: 32 : const SwFrm* pTmpFrm = pFrm->FindTabFrm();
188 [ + - ]: 32 : if( !pTmpFrm )
189 : 32 : pTmpFrm = pFrm;
190 : 32 : nRedX = text::HoriOrientation::LEFT == eHor ? pTmpFrm->Frm().Left() - REDLINE_DISTANCE :
191 [ + - ]: 64 : pTmpFrm->Frm().Right() + REDLINE_DISTANCE;
192 : : }
193 : 32 : }
194 : :
195 : 6 : void SwExtraPainter::PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed )
196 : : {
197 : : // Line number is stronger than the divider
198 : 12 : const XubString aTmp( HasNumber() ? rLineInf.GetNumType().GetNumStr( nLineNr )
199 [ # # ]: 12 : : rLineInf.GetDivider() );
[ + - + - ]
200 : :
201 : : // Get script type of line numbering:
202 [ + - ]: 6 : pFnt->SetActual( SwScriptInfo::WhichFont( 0, &aTmp, 0 ) );
203 : :
204 : 6 : SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), 0, aTmp, 0, aTmp.Len() );
205 : 6 : aDrawInf.SetSpace( 0 );
206 : 6 : aDrawInf.SetWrong( NULL );
207 : 6 : aDrawInf.SetGrammarCheck( NULL );
208 : 6 : aDrawInf.SetSmartTags( NULL ); // SMARTTAGS
209 : 6 : aDrawInf.SetLeft( 0 );
210 : 6 : aDrawInf.SetRight( LONG_MAX );
211 : 6 : aDrawInf.SetFrm( pTxtFrm );
212 : 6 : aDrawInf.SetFont( pFnt );
213 : 6 : aDrawInf.SetSnapToGrid( sal_False );
214 : 6 : aDrawInf.SetIgnoreFrmRTL( sal_True );
215 : :
216 : 6 : sal_Bool bTooBig = pFnt->GetSize( pFnt->GetActual() ).Height() > nMax &&
217 [ # # ][ # # ]: 6 : pFnt->GetHeight( pSh, *pSh->GetOut() ) > nMax;
[ - + ]
218 : : SwFont* pTmpFnt;
219 [ - + ]: 6 : if( bTooBig )
220 : : {
221 [ # # ][ # # ]: 0 : pTmpFnt = new SwFont( *GetFont() );
222 [ # # ]: 0 : if( nMax >= 20 )
223 : : {
224 : 0 : nMax *= 17;
225 : 0 : nMax /= 20;
226 : : }
227 [ # # ]: 0 : pTmpFnt->SetSize( Size( 0, nMax ), pTmpFnt->GetActual() );
228 : : }
229 : : else
230 : 6 : pTmpFnt = GetFont();
231 : 6 : Point aTmpPos( nX, nY );
232 : 6 : aTmpPos.Y() += nAsc;
233 : 6 : sal_Bool bPaint = sal_True;
234 [ + - ]: 6 : if( !IsClipChg() )
235 : : {
236 [ + - ]: 6 : Size aSize = pTmpFnt->_GetTxtSize( aDrawInf );
237 [ + - ]: 6 : if( bGoLeft )
238 : 6 : aTmpPos.X() -= aSize.Width();
239 : : // calculate rectangle containing the line number
240 : 6 : SwRect aRct( Point( aTmpPos.X(),
241 [ + - ]: 6 : aTmpPos.Y() - pTmpFnt->GetAscent( pSh, *pSh->GetOut() )
242 : 6 : ), aSize );
243 [ + + ][ + - ]: 6 : if( !aRect.IsInside( aRct ) )
244 : : {
245 [ + - ][ + + ]: 4 : if( aRct.Intersection( aRect ).IsEmpty() )
246 : 3 : bPaint = sal_False;
247 : : else
248 [ + - ]: 6 : aClip.ChgClip( aRect, pTxtFrm );
249 : : }
250 : : }
251 [ # # ]: 0 : else if( bGoLeft )
252 [ # # ]: 0 : aTmpPos.X() -= pTmpFnt->_GetTxtSize( aDrawInf ).Width();
253 : 6 : aDrawInf.SetPos( aTmpPos );
254 [ + + ]: 6 : if( bPaint )
255 [ + - ]: 3 : pTmpFnt->_DrawText( aDrawInf );
256 : :
257 [ - + ]: 6 : if( bTooBig )
258 [ # # ][ # # ]: 0 : delete pTmpFnt;
259 [ - + ]: 6 : if( bRed )
260 : : {
261 [ # # ]: 0 : long nDiff = bGoLeft ? nRedX - nX : nX - nRedX;
262 [ # # ]: 0 : if( nDiff > REDLINE_MINDIST )
263 [ # # ]: 0 : PaintRedline( nY, nMax );
264 [ + - ]: 6 : }
265 : 6 : }
266 : :
267 : 0 : void SwExtraPainter::PaintRedline( SwTwips nY, long nMax )
268 : : {
269 : 0 : Point aStart( nRedX, nY );
270 : 0 : Point aEnd( nRedX, nY + nMax );
271 : :
272 [ # # ]: 0 : if( !IsClipChg() )
273 : : {
274 : 0 : SwRect aRct( aStart, aEnd );
275 [ # # ][ # # ]: 0 : if( !aRect.IsInside( aRct ) )
276 : : {
277 [ # # ][ # # ]: 0 : if( aRct.Intersection( aRect ).IsEmpty() )
278 : 0 : return;
279 [ # # ]: 0 : aClip.ChgClip( aRect, pTxtFrm );
280 : : }
281 : : }
282 : 0 : const Color aOldCol( pSh->GetOut()->GetLineColor() );
283 [ # # ][ # # ]: 0 : pSh->GetOut()->SetLineColor( SW_MOD()->GetRedlineMarkColor() );
[ # # ]
284 : :
285 [ # # ][ # # ]: 0 : if ( pTxtFrm->IsVertical() )
286 : : {
287 [ # # ]: 0 : pTxtFrm->SwitchHorizontalToVertical( aStart );
288 [ # # ]: 0 : pTxtFrm->SwitchHorizontalToVertical( aEnd );
289 : : }
290 : :
291 [ # # ]: 0 : pSh->GetOut()->DrawLine( aStart, aEnd );
292 [ # # ]: 0 : pSh->GetOut()->SetLineColor( aOldCol );
293 : : }
294 : :
295 : 32 : void SwTxtFrm::PaintExtraData( const SwRect &rRect ) const
296 : : {
297 [ + - ][ - + ]: 32 : if( Frm().Top() > rRect.Bottom() || Frm().Bottom() < rRect.Top() )
[ - + ]
298 : 0 : return;
299 : :
300 : 32 : const SwTxtNode& rTxtNode = *GetTxtNode();
301 : 32 : const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess();
302 : 32 : const SwLineNumberInfo &rLineInf = rTxtNode.getIDocumentLineNumberAccess()->GetLineNumberInfo();
303 : 32 : const SwFmtLineNumber &rLineNum = GetAttrSet()->GetLineNumber();
304 : 64 : sal_Bool bLineNum = !IsInTab() && rLineInf.IsPaintLineNumbers() &&
305 [ - + ][ # # ]: 64 : ( !IsInFly() || rLineInf.IsCountInFlys() ) && rLineNum.IsCount();
[ + - ]
[ + - + - ]
306 : 32 : sal_Int16 eHor = (sal_Int16)SW_MOD()->GetRedlineMarkPos();
307 [ - + ][ - + ]: 32 : if( eHor != text::HoriOrientation::NONE && !IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) )
[ + - ]
308 : 0 : eHor = text::HoriOrientation::NONE;
309 : 32 : sal_Bool bRedLine = eHor != text::HoriOrientation::NONE;
310 [ - + ][ # # ]: 32 : if ( bLineNum || bRedLine )
311 : : {
312 [ + - ][ + - ]: 32 : if( IsLocked() || IsHiddenNow() || !Prt().Height() )
[ + - ][ - + ]
[ + - ]
313 : : return;
314 : 32 : ViewShell *pSh = getRootFrm()->GetCurrShell();
315 : :
316 [ - + ][ # # ]: 32 : SWAP_IF_NOT_SWAPPED( this )
[ - + ][ # # ]
[ + - ]
317 : 32 : SwRect rOldRect( rRect );
318 : :
319 [ - + ][ + - ]: 32 : if ( IsVertical() )
320 [ # # ]: 0 : SwitchVerticalToHorizontal( (SwRect&)rRect );
321 : :
322 [ + - ]: 32 : SwLayoutModeModifier aLayoutModeModifier( *pSh->GetOut() );
323 [ + - ]: 32 : aLayoutModeModifier.Modify( sal_False );
324 : :
325 : : // #i16816# tagged pdf support
326 [ + - ]: 32 : SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
327 : :
328 [ + - ]: 32 : SwExtraPainter aExtra( this, pSh, rLineInf, rRect, eHor, bLineNum );
329 : :
330 [ + - ][ + + ]: 32 : if( HasPara() )
331 : : {
332 : 26 : SwTxtFrmLocker aLock((SwTxtFrm*)this);
333 : :
334 [ + - ]: 26 : SwTxtLineAccess aAccess( (SwTxtFrm*)this );
335 [ + - ]: 26 : aAccess.GetPara();
336 : :
337 [ + - ]: 26 : SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect );
338 : :
339 [ + - ]: 26 : aLayoutModeModifier.Modify( sal_False );
340 : :
341 [ + - ]: 26 : SwTxtPainter aLine( (SwTxtFrm*)this, &aInf );
342 : 26 : sal_Bool bNoDummy = !aLine.GetNext(); // Only one empty line!
343 : :
344 [ - + ]: 26 : while( aLine.Y() + aLine.GetLineHeight() <= rRect.Top() )
345 : : {
346 [ # # # # : 0 : if( !aLine.GetCurr()->IsDummy() &&
# # ][ # # ]
347 : 0 : ( rLineInf.IsCountBlankLines() ||
348 : 0 : aLine.GetCurr()->HasCntnt() ) )
349 : 0 : aExtra.IncLineNr();
350 [ # # ][ # # ]: 0 : if( !aLine.Next() )
351 : : {
352 : 0 : (SwRect&)rRect = rOldRect;
353 [ # # ][ # # ]: 0 : UNDO_SWAP( this )
354 : : return;
355 : : }
356 : : }
357 : :
358 : 26 : long nBottom = rRect.Bottom();
359 : :
360 : 26 : sal_Bool bNoPrtLine = 0 == GetMinPrtLine();
361 [ - + ]: 26 : if( !bNoPrtLine )
362 : : {
363 [ # # ]: 0 : while ( aLine.Y() < GetMinPrtLine() )
364 : : {
365 [ # # ]: 0 : if( ( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() )
[ # # # # ]
[ # # ]
366 : 0 : && !aLine.GetCurr()->IsDummy() )
367 : 0 : aExtra.IncLineNr();
368 [ # # ][ # # ]: 0 : if( !aLine.Next() )
369 : 0 : break;
370 : : }
371 : 0 : bNoPrtLine = aLine.Y() >= GetMinPrtLine();
372 : : }
373 [ + - ]: 26 : if( bNoPrtLine )
374 : : {
375 [ - + # # ]: 26 : do
[ - + ]
376 : : {
377 [ - + ][ # # ]: 26 : if( bNoDummy || !aLine.GetCurr()->IsDummy() )
[ + - ]
378 : : {
379 [ + - ][ - + ]: 26 : sal_Bool bRed = bRedLine && aLine.GetCurr()->HasRedline();
380 [ + + ][ + - ]: 26 : if( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() )
[ + - ]
381 : : {
382 [ + - + + : 72 : if( bLineNum &&
- + ][ + + ]
383 : 46 : ( aExtra.HasNumber() || aExtra.HasDivider() ) )
384 : : {
385 : : KSHORT nTmpHeight, nTmpAscent;
386 [ + - ]: 6 : aLine.CalcAscentAndHeight( nTmpAscent, nTmpHeight );
387 : : aExtra.PaintExtra( aLine.Y(), nTmpAscent,
388 [ + - ]: 6 : nTmpHeight, bRed );
389 : 6 : bRed = sal_False;
390 : : }
391 : 26 : aExtra.IncLineNr();
392 : : }
393 [ - + ]: 26 : if( bRed )
394 [ # # ]: 0 : aExtra.PaintRedline( aLine.Y(), aLine.GetLineHeight() );
395 : : }
396 [ + - ]: 26 : } while( aLine.Next() && aLine.Y() <= nBottom );
397 [ + - ][ - + ]: 26 : }
[ + - ][ - + ]
[ + - ][ - + ]
[ + - ]
398 : : }
399 : : else
400 : : {
401 [ + - ]: 6 : bRedLine &= ( MSHRT_MAX!= pIDRA->GetRedlinePos(rTxtNode, USHRT_MAX) );
402 : :
403 [ + - ][ + + : 14 : if( bLineNum && rLineInf.IsCountBlankLines() &&
+ - - + ]
[ - + ]
404 : 8 : ( aExtra.HasNumber() || aExtra.HasDivider() ) )
405 : : {
406 : 0 : aExtra.PaintExtra( Frm().Top()+Prt().Top(), aExtra.GetFont()
407 [ # # # # ]: 0 : ->GetAscent( pSh, *pSh->GetOut() ), Prt().Height(), bRedLine );
408 : : }
409 [ - + ]: 6 : else if( bRedLine )
410 [ # # ]: 0 : aExtra.PaintRedline( Frm().Top()+Prt().Top(), Prt().Height() );
411 : : }
412 : :
413 : 32 : (SwRect&)rRect = rOldRect;
414 [ # # ][ + - ]: 32 : UNDO_SWAP( this )
[ - + ][ + - ]
[ - + ][ + - ]
[ + - ][ - + ]
415 : : }
416 : : }
417 : :
418 : 12924 : SwRect SwTxtFrm::Paint()
419 : : {
420 : : #if OSL_DEBUG_LEVEL > 1
421 : : const SwTwips nDbgY = Frm().Top();
422 : : (void)nDbgY;
423 : : #endif
424 : :
425 : : // finger layout
426 : : OSL_ENSURE( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
427 : :
428 : 12924 : SwRect aRet( Prt() );
429 [ + + ][ + + ]: 12924 : if ( IsEmpty() || !HasPara() )
[ + + ]
430 : 1750 : aRet += Frm().Pos();
431 : : else
432 : : {
433 : : // We return the right paint rect. Use the calculated PaintOfst as the
434 : : // left margin
435 : 11174 : SwRepaint *pRepaint = GetPara()->GetRepaint();
436 : : long l;
437 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
438 [ - + ]: 11174 : if ( IsVertLR() ) // mba: the following line was added, but we don't need it for the existing directions; kept for IsVertLR(), but should be checked
439 : 0 : pRepaint->Chg( ( GetUpper()->Frm() ).Pos() + ( GetUpper()->Prt() ).Pos(), ( GetUpper()->Prt() ).SSize() );
440 : :
441 [ + + ]: 11174 : if( pRepaint->GetOfst() )
442 : 1064 : pRepaint->Left( pRepaint->GetOfst() );
443 : :
444 : 11174 : l = pRepaint->GetRightOfst();
445 [ + + ][ + + ]: 11174 : if( l && ( pRepaint->GetOfst() || l > pRepaint->Right() ) )
[ + + ][ + - ]
446 : 3308 : pRepaint->Right( l );
447 : 11174 : pRepaint->SetOfst( 0 );
448 : 11174 : aRet = *pRepaint;
449 : :
450 [ - + ]: 11174 : if ( IsRightToLeft() )
451 : 0 : SwitchLTRtoRTL( aRet );
452 : :
453 [ - + ]: 11174 : if ( IsVertical() )
454 : 0 : SwitchHorizontalToVertical( aRet );
455 : : }
456 : 12924 : ResetRepaint();
457 : :
458 : 12924 : return aRet;
459 : : }
460 : :
461 : 6339 : sal_Bool SwTxtFrm::PaintEmpty( const SwRect &rRect, sal_Bool bCheck ) const
462 : : {
463 : 6339 : ViewShell *pSh = getRootFrm()->GetCurrShell();
464 [ + + ][ + + ]: 6339 : if( pSh && ( pSh->GetViewOptions()->IsParagraph() || bInitFont ) )
[ + + ][ + - ]
465 : : {
466 : 70 : bInitFont = sal_False;
467 [ + - ]: 70 : SwTxtFly aTxtFly( this );
468 : 70 : aTxtFly.SetTopRule();
469 : 70 : SwRect aRect;
470 [ + + ][ + - ]: 70 : if( bCheck && aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
[ - + ][ - + ]
[ + - ]
471 : 0 : return sal_False;
472 [ + + ]: 70 : else if( pSh->GetWin() )
473 : : {
474 : : SwFont *pFnt;
475 : 67 : const SwTxtNode& rTxtNode = *GetTxtNode();
476 [ + + ][ + - ]: 67 : if ( rTxtNode.HasSwAttrSet() )
477 : : {
478 [ + - ]: 3 : const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() );
479 [ + - ][ + - ]: 3 : pFnt = new SwFont( pAttrSet, rTxtNode.getIDocumentSettingAccess() );
[ + - ]
480 : : }
481 : : else
482 : : {
483 [ + - ]: 64 : SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh );
484 [ + - ][ + - ]: 64 : pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
[ + - ][ + - ]
485 : : }
486 : :
487 [ + - ]: 67 : const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess();
488 [ + - ][ + - ]: 67 : if( IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) )
489 : : {
490 [ + - ]: 67 : MSHORT nRedlPos = pIDRA->GetRedlinePos( rTxtNode, USHRT_MAX );
491 [ - + ]: 67 : if( MSHRT_MAX != nRedlPos )
492 : : {
493 [ # # ]: 0 : SwAttrHandler aAttrHandler;
494 [ # # ]: 0 : aAttrHandler.Init( rTxtNode.GetSwAttrSet(),
495 [ # # ][ # # ]: 0 : *rTxtNode.getIDocumentSettingAccess(), NULL );
496 [ # # ][ # # ]: 0 : SwRedlineItr aRedln( rTxtNode, *pFnt, aAttrHandler, nRedlPos, sal_True );
[ # # ]
497 : : }
498 : : }
499 : :
500 [ + + ][ + - ]: 67 : if( pSh->GetViewOptions()->IsParagraph() && Prt().Height() )
[ + + ]
501 : : {
502 [ + - ][ - + ]: 23 : if( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet( SW_LATIN ) &&
[ # # ][ - + ]
503 [ # # ][ # # ]: 0 : pFnt->GetName( SW_LATIN ) != numfunc::GetDefBulletFontname() )
[ # # ]
504 : : {
505 [ # # ]: 0 : pFnt->SetFamily( FAMILY_DONTKNOW, SW_LATIN );
506 [ # # ][ # # ]: 0 : pFnt->SetName( numfunc::GetDefBulletFontname(), SW_LATIN );
507 [ # # ]: 0 : pFnt->SetStyleName( aEmptyStr, SW_LATIN );
508 [ # # ]: 0 : pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, SW_LATIN );
509 : : }
510 [ + - ][ + - ]: 23 : pFnt->SetVertical( 0, IsVertical() );
511 [ + - ]: 23 : SwFrmSwapper aSwapper( this, sal_True );
512 [ + - ]: 23 : SwLayoutModeModifier aLayoutModeModifier( *pSh->GetOut() );
513 [ + - ][ + - ]: 23 : aLayoutModeModifier.Modify( IsRightToLeft() );
514 : :
515 : 23 : pFnt->Invalidate();
516 [ + - ]: 23 : pFnt->ChgPhysFnt( pSh, *pSh->GetOut() );
517 : 23 : Point aPos = Frm().Pos() + Prt().Pos();
518 : :
519 : : const SvxLRSpaceItem &rSpace =
520 [ + - ][ + - ]: 23 : GetTxtNode()->GetSwAttrSet().GetLRSpace();
521 : :
522 [ - + ]: 23 : if ( rSpace.GetTxtFirstLineOfst() > 0 )
523 : 0 : aPos.X() += rSpace.GetTxtFirstLineOfst();
524 : :
525 : : SwSaveClip *pClip;
526 [ - + ]: 23 : if( IsUndersized() )
527 : : {
528 [ # # ][ # # ]: 0 : pClip = new SwSaveClip( pSh->GetOut() );
529 [ # # ]: 0 : pClip->ChgClip( rRect );
530 : : }
531 : : else
532 : 23 : pClip = NULL;
533 : :
534 [ + - ]: 23 : aPos.Y() += pFnt->GetAscent( pSh, *pSh->GetOut() );
535 : :
536 [ + - ][ + - ]: 46 : if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() &&
[ + - ][ + - ]
[ + - ]
537 [ + - ]: 23 : IsInDocBody() )
538 : : {
539 [ + - ][ + - ]: 23 : GETGRID( FindPageFrm() )
[ + - ][ - + ]
[ # # ][ # # ]
[ # # ][ - + ]
540 [ - + ]: 23 : if ( pGrid )
541 : : {
542 : : // center character in grid line
543 : 0 : aPos.Y() += ( pGrid->GetBaseHeight() -
544 [ # # ]: 0 : pFnt->GetHeight( pSh, *pSh->GetOut() ) ) / 2;
545 : :
546 [ # # ]: 0 : if ( ! pGrid->GetRubyTextBelow() )
547 : 0 : aPos.Y() += pGrid->GetRubyHeight();
548 : : }
549 : : }
550 : :
551 : : // Don't show the paragraph mark for collapsed paragraphs, when they are hidden
552 [ + - ][ + - ]: 23 : if ( EmptyHeight( ) > 1 )
553 : : {
554 : 23 : const rtl::OUString aTmp( CH_PAR );
555 [ + - ][ + - ]: 23 : SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), 0, aTmp, 0, 1 );
556 : 23 : aDrawInf.SetLeft( rRect.Left() );
557 : 23 : aDrawInf.SetRight( rRect.Right() );
558 : 23 : aDrawInf.SetPos( aPos );
559 : 23 : aDrawInf.SetSpace( 0 );
560 : 23 : aDrawInf.SetKanaComp( 0 );
561 : 23 : aDrawInf.SetWrong( NULL );
562 : 23 : aDrawInf.SetGrammarCheck( NULL );
563 : 23 : aDrawInf.SetSmartTags( NULL ); // SMARTTAGS
564 : 23 : aDrawInf.SetFrm( this );
565 : 23 : aDrawInf.SetFont( pFnt );
566 : 23 : aDrawInf.SetSnapToGrid( sal_False );
567 : :
568 [ + - ]: 23 : pFnt->_DrawText( aDrawInf );
569 : : }
570 [ - + ][ # # ]: 23 : delete pClip;
[ + - ][ + - ]
571 : : }
572 [ + - ][ + - ]: 67 : delete pFnt;
573 : 70 : return sal_True;
574 [ + - ][ + + ]: 70 : }
575 : : }
576 : : else
577 : 6339 : return sal_True;
578 : 70 : return sal_False;
579 : : }
580 : :
581 : 20171 : void SwTxtFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
582 : : {
583 : 20171 : ResetRepaint();
584 : :
585 : : // #i16816# tagged pdf support
586 : 20171 : ViewShell *pSh = getRootFrm()->GetCurrShell();
587 : :
588 : 20171 : Num_Info aNumInfo( *this );
589 [ + - ]: 20171 : SwTaggedPDFHelper aTaggedPDFHelperNumbering( &aNumInfo, 0, 0, *pSh->GetOut() );
590 : :
591 : 20171 : Frm_Info aFrmInfo( *this );
592 [ + - ]: 20171 : SwTaggedPDFHelper aTaggedPDFHelperParagraph( 0, &aFrmInfo, 0, *pSh->GetOut() );
593 : :
594 [ + + ][ + - ]: 20171 : if( !IsEmpty() || !PaintEmpty( rRect, sal_True ) )
[ + + ][ + + ]
595 : : {
596 : : #if OSL_DEBUG_LEVEL > 1
597 : : const SwTwips nDbgY = Frm().Top();
598 : : (void)nDbgY;
599 : : #endif
600 : :
601 [ + - ][ + - ]: 13838 : if( IsLocked() || IsHiddenNow() || ! Prt().HasArea() )
[ + + ][ + - ]
[ - + ][ + + ]
602 : : return;
603 : :
604 : : // It can happen that the IdleCollector withdrew my cached information
605 [ + - ][ + + ]: 13784 : if( !HasPara() )
606 : : {
607 : : OSL_ENSURE( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
608 : :
609 : : // #i29062# pass info that we are currently
610 : : // painting.
611 [ + - ]: 3 : ((SwTxtFrm*)this)->GetFormatted( true );
612 [ + - ]: 3 : if( IsEmpty() )
613 : : {
614 [ + - ]: 3 : PaintEmpty( rRect, sal_False );
615 : : return;
616 : : }
617 [ # # ][ # # ]: 0 : if( !HasPara() )
618 : : {
619 : : OSL_ENSURE( !this, "+SwTxtFrm::Paint: missing format information" );
620 : : return;
621 : : }
622 : : }
623 : :
624 : : // We don't want to be interrupted while painting.
625 : : // Do that after thr Format()!
626 : 13781 : SwTxtFrmLocker aLock((SwTxtFrm*)this);
627 : :
628 : : // We only paint the part of the TxtFrm which changed, is within the
629 : : // range and was requested to paint.
630 : : // One could think that the area rRect _needs_ to be painted, although
631 : : // rRepaint is set. Indeed, we cannot avoid this problem from a formal
632 : : // perspective. Luckily we can assume rRepaint to be empty when we need
633 : : // paint the while Frm.
634 [ + - ]: 13781 : SwTxtLineAccess aAccess( (SwTxtFrm*)this );
635 [ + - ]: 13781 : SwParaPortion *pPara = aAccess.GetPara();
636 : :
637 : 13781 : SwRepaint &rRepaint = *(pPara->GetRepaint());
638 : :
639 : : // Switch off recycling when in the FlyCntFrm.
640 : : // A DrawRect is called for repainting the line anyways.
641 [ - + ]: 13781 : if( rRepaint.GetOfst() )
642 : : {
643 [ # # ]: 0 : const SwFlyFrm *pFly = FindFlyFrm();
644 [ # # ][ # # ]: 0 : if( pFly && pFly->IsFlyInCntFrm() )
[ # # ]
645 : 0 : rRepaint.SetOfst( 0 );
646 : : }
647 : :
648 : : // Ge the String for painting. The length is of special interest.
649 : :
650 : : // Rectangle
651 : : OSL_ENSURE( ! IsSwapped(), "A frame is swapped before Paint" );
652 : 13781 : SwRect aOldRect( rRect );
653 : :
654 [ - + ][ # # ]: 13781 : SWAP_IF_NOT_SWAPPED( this )
[ - + ][ # # ]
[ + - ]
655 : :
656 [ + - ][ - + ]: 13781 : if ( IsVertical() )
657 [ # # ]: 0 : SwitchVerticalToHorizontal( (SwRect&)rRect );
658 : :
659 [ + - ][ - + ]: 13781 : if ( IsRightToLeft() )
660 [ # # ]: 0 : SwitchRTLtoLTR( (SwRect&)rRect );
661 : :
662 [ + - ]: 13781 : SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect );
663 [ + - ]: 13781 : aInf.SetWrongList( ( (SwTxtNode*)GetTxtNode() )->GetWrong() );
664 [ + - ]: 13781 : aInf.SetGrammarCheckList( ( (SwTxtNode*)GetTxtNode() )->GetGrammarCheck() );
665 [ + - ]: 13781 : aInf.SetSmartTags( ( (SwTxtNode*)GetTxtNode() )->GetSmartTags() ); // SMARTTAGS
666 : 13781 : aInf.GetTxtFly()->SetTopRule();
667 : :
668 [ + - ]: 13781 : SwTxtPainter aLine( (SwTxtFrm*)this, &aInf );
669 : : // Optimization: if no free flying Frm overlaps into our line, the
670 : : // SwTxtFly just switches off
671 [ + - ]: 13781 : aInf.GetTxtFly()->Relax();
672 : :
673 : 13781 : OutputDevice* pOut = aInf.GetOut();
674 : 13781 : const sal_Bool bOnWin = pSh->GetWin() != 0;
675 : :
676 [ - + ][ + - ]: 13781 : SwSaveClip aClip( bOnWin || IsUndersized() ? pOut : 0 );
[ + + ]
677 : :
678 : : // Output loop: For each Line ... (which is still visible) ...
679 : : // adapt rRect (Top + 1, Bottom - 1)
680 : : // Because the Iterator attaches the Lines without a gap to each other
681 [ + - ]: 13781 : aLine.TwipsToLine( rRect.Top() + 1 );
682 : 13781 : long nBottom = rRect.Bottom();
683 : :
684 : 13781 : sal_Bool bNoPrtLine = 0 == GetMinPrtLine();
685 [ - + ]: 13781 : if( !bNoPrtLine )
686 : : {
687 [ # # ][ # # ]: 0 : while ( aLine.Y() < GetMinPrtLine() && aLine.Next() )
[ # # ][ # # ]
688 : : ;
689 : 0 : bNoPrtLine = aLine.Y() >= GetMinPrtLine();
690 : : }
691 [ + - ]: 13781 : if( bNoPrtLine )
692 : : {
693 [ + + + + ]: 47337 : do
[ + + ]
694 : : {
695 [ + - ]: 30292 : aLine.DrawTextLine( rRect, aClip, IsUndersized() );
696 : :
697 [ + - ]: 47337 : } while( aLine.Next() && aLine.Y() <= nBottom );
698 : : }
699 : :
700 : : // Once is enough:
701 [ - + ]: 13781 : if( aLine.IsPaintDrop() )
702 [ # # ]: 0 : aLine.PaintDropPortion();
703 : :
704 [ + - ][ + + ]: 13781 : if( rRepaint.HasArea() )
705 : 7337 : rRepaint.Clear();
706 : :
707 [ - + ][ # # ]: 13781 : UNDO_SWAP( this )
708 : 13781 : (SwRect&)rRect = aOldRect;
709 : :
710 [ + - ][ + - ]: 20171 : OSL_ENSURE( ! IsSwapped(), "A frame is swapped after Paint" );
[ + - ][ + - ]
711 [ + - ][ + + ]: 20171 : }
[ + - ][ + + ]
712 : : }
713 : :
714 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|