xref: /trunk/main/sw/source/core/text/porexp.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <viewopt.hxx>  // SwViewOptions
33 #include <SwPortionHandler.hxx>
34 #include <inftxt.hxx>
35 #include <porexp.hxx>
36 
37 /*************************************************************************
38  *                      class SwExpandPortion
39  *************************************************************************/
40 
41 xub_StrLen SwExpandPortion::GetCrsrOfst( const MSHORT nOfst ) const
42 { return SwLinePortion::GetCrsrOfst( nOfst ); }
43 
44 /*************************************************************************
45  *              virtual SwExpandPortion::GetExpTxt()
46  *************************************************************************/
47 
48 sal_Bool SwExpandPortion::GetExpTxt( const SwTxtSizeInfo&,
49                                  XubString &rTxt ) const
50 {
51     rTxt.Erase();
52     // Nicht etwa: return 0 != rTxt.Len();
53     // Weil: leere Felder ersetzen CH_TXTATR gegen einen Leerstring
54     return sal_True;
55 }
56 
57 /*************************************************************************
58  *              virtual SwExpandPortion::HandlePortion()
59  *************************************************************************/
60 
61 void SwExpandPortion::HandlePortion( SwPortionHandler& rPH ) const
62 {
63     String aString;
64     rPH.Special( GetLen(), aString, GetWhichPor() );
65 }
66 
67 /*************************************************************************
68  *              virtual SwExpandPortion::GetTxtSize()
69  *************************************************************************/
70 
71 SwPosSize SwExpandPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
72 {
73     SwTxtSlot aDiffTxt( &rInf, this, false, false );
74     return rInf.GetTxtSize();
75 }
76 
77 /*************************************************************************
78  *                 virtual SwExpandPortion::Format()
79  *************************************************************************/
80 
81 // 5010: Exp und Tabs
82 
83 sal_Bool SwExpandPortion::Format( SwTxtFormatInfo &rInf )
84 {
85     SwTxtSlot aDiffTxt( &rInf, this, true, false );
86     const xub_StrLen nFullLen = rInf.GetLen();
87 
88     // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der
89     // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs)
90     // sal_False returnen wegen SetFull ...
91     if( !nFullLen )
92     {
93         // nicht Init(), weil wir Hoehe und Ascent brauchen
94         Width(0);
95         return sal_False;
96     }
97     return SwTxtPortion::Format( rInf );
98 }
99 
100 /*************************************************************************
101  *              virtual SwExpandPortion::Paint()
102  *************************************************************************/
103 
104 void SwExpandPortion::Paint( const SwTxtPaintInfo &rInf ) const
105 {
106     SwTxtSlot aDiffTxt( &rInf, this, true, true );
107 
108     rInf.DrawBackBrush( *this );
109 
110     // do we have to repaint a post it portion?
111     if( rInf.OnWin() && pPortion && !pPortion->Width() )
112         pPortion->PrePaint( rInf, this );
113 
114     // The contents of field portions is not considered during the
115     // calculation of the directions. Therefore we let vcl handle
116     // the calculation by removing the BIDI_STRONG_FLAG temporarily.
117     SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
118     aLayoutModeModifier.SetAuto();
119 
120     // ST2
121     if ( rInf.GetSmartTags() || rInf.GetGrammarCheckList() )
122         rInf.DrawMarkedText( *this, rInf.GetLen(), sal_False, sal_False,
123             0 != rInf.GetSmartTags(), 0 != rInf.GetGrammarCheckList() );
124     else
125         rInf.DrawText( *this, rInf.GetLen(), sal_False );
126 }
127 
128 /*************************************************************************
129  *                      class SwBlankPortion
130  *************************************************************************/
131 
132 SwLinePortion *SwBlankPortion::Compress() { return this; }
133 
134 /*************************************************************************
135  *                 SwBlankPortion::MayUnderFlow()
136  *************************************************************************/
137 
138 // 5497: Es gibt schon Gemeinheiten auf der Welt...
139 // Wenn eine Zeile voll mit HardBlanks ist und diese ueberlaeuft,
140 // dann duerfen keine Underflows generiert werden!
141 // Komplikationen bei Flys...
142 
143 MSHORT SwBlankPortion::MayUnderFlow( const SwTxtFormatInfo &rInf,
144     xub_StrLen nIdx, sal_Bool bUnderFlow ) const
145 {
146     if( rInf.StopUnderFlow() )
147         return 0;
148     const SwLinePortion *pPos = rInf.GetRoot();
149     if( pPos->GetPortion() )
150         pPos = pPos->GetPortion();
151     while( pPos && pPos->IsBlankPortion() )
152         pPos = pPos->GetPortion();
153     if( !pPos || !rInf.GetIdx() || ( !pPos->GetLen() && pPos == rInf.GetRoot() ) )
154         return 0; // Nur noch BlankPortions unterwegs
155     // Wenn vor uns ein Blank ist, brauchen wir kein Underflow ausloesen,
156     // wenn hinter uns ein Blank ist, brauchen wir kein Underflow weiterreichen
157     if( bUnderFlow && CH_BLANK == rInf.GetTxt().GetChar( nIdx + 1) )
158         return 0;
159     if( nIdx && !((SwTxtFormatInfo&)rInf).GetFly() )
160     {
161         while( pPos && !pPos->IsFlyPortion() )
162             pPos = pPos->GetPortion();
163         if( !pPos )
164         {
165         //Hier wird ueberprueft, ob es in dieser Zeile noch sinnvolle Umbrueche
166         //gibt, Blanks oder Felder etc., wenn nicht, kein Underflow.
167         //Wenn Flys im Spiel sind, lassen wir das Underflow trotzdem zu.
168             xub_StrLen nBlank = nIdx;
169             while( --nBlank > rInf.GetLineStart() )
170             {
171                 const xub_Unicode cCh = rInf.GetChar( nBlank );
172                 if( CH_BLANK == cCh ||
173                     (( CH_TXTATR_BREAKWORD == cCh || CH_TXTATR_INWORD == cCh )
174                         && rInf.HasHint( nBlank ) ) )
175                     break;
176             }
177             if( nBlank <= rInf.GetLineStart() )
178                 return 0;
179         }
180     }
181     xub_Unicode cCh;
182     if( nIdx < 2 || CH_BLANK == (cCh = rInf.GetChar( nIdx - 1 )) )
183         return 1;
184     if( CH_BREAK == cCh )
185         return 0;
186     return 2;
187 }
188 
189 /*************************************************************************
190  *                 virtual SwBlankPortion::FormatEOL()
191  *************************************************************************/
192 // Format end of Line
193 
194 void SwBlankPortion::FormatEOL( SwTxtFormatInfo &rInf )
195 {
196     MSHORT nMay = MayUnderFlow( rInf, rInf.GetIdx() - nLineLength, sal_True );
197     if( nMay )
198     {
199         if( nMay > 1 )
200         {
201             if( rInf.GetLast() == this )
202                rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
203             rInf.X( rInf.X() - PrtWidth() );
204             rInf.SetIdx( rInf.GetIdx() - GetLen() );
205         }
206         Truncate();
207         rInf.SetUnderFlow( this );
208         if( rInf.GetLast()->IsKernPortion() )
209             rInf.SetUnderFlow( rInf.GetLast() );
210     }
211 }
212 
213 /*************************************************************************
214  *                 virtual SwBlankPortion::Format()
215  *************************************************************************/
216 
217 // 7771: UnderFlows weiterreichen und selbst ausloesen!
218 sal_Bool SwBlankPortion::Format( SwTxtFormatInfo &rInf )
219 {
220     const sal_Bool bFull = rInf.IsUnderFlow() || SwExpandPortion::Format( rInf );
221     if( bFull && MayUnderFlow( rInf, rInf.GetIdx(), rInf.IsUnderFlow() ) )
222     {
223         Truncate();
224         rInf.SetUnderFlow( this );
225         if( rInf.GetLast()->IsKernPortion() )
226             rInf.SetUnderFlow( rInf.GetLast() );
227     }
228     return bFull;
229 }
230 
231 /*************************************************************************
232  *                 virtual SwBlankPortion::Paint()
233  *************************************************************************/
234 
235 void SwBlankPortion::Paint( const SwTxtPaintInfo &rInf ) const
236 {
237     if( !bMulti ) // No gray background for multiportion brackets
238         rInf.DrawViewOpt( *this, POR_BLANK );
239     SwExpandPortion::Paint( rInf );
240 }
241 
242 /*************************************************************************
243  *              virtual SwBlankPortion::GetExpTxt()
244  *************************************************************************/
245 
246 sal_Bool SwBlankPortion::GetExpTxt( const SwTxtSizeInfo&, XubString &rTxt ) const
247 {
248     rTxt = cChar;
249     return sal_True;
250 }
251 
252 /*************************************************************************
253  *              virtual SwBlankPortion::HandlePortion()
254  *************************************************************************/
255 
256 void SwBlankPortion::HandlePortion( SwPortionHandler& rPH ) const
257 {
258     String aString( cChar );
259     rPH.Special( GetLen(), aString, GetWhichPor() );
260 }
261 
262 /*************************************************************************
263  *                      class SwPostItsPortion
264  *************************************************************************/
265 
266 SwPostItsPortion::SwPostItsPortion( sal_Bool bScrpt )
267     : nViewWidth(0), bScript( bScrpt )
268 {
269     nLineLength = 1;
270     SetWhichPor( POR_POSTITS );
271 }
272 
273 void SwPostItsPortion::Paint( const SwTxtPaintInfo &rInf ) const
274 {
275     if( rInf.OnWin() && Width() )
276         rInf.DrawPostIts( *this, IsScript() );
277 }
278 
279 KSHORT SwPostItsPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
280 {
281     // Nicht zu fassen: PostIts sind immer zu sehen.
282     return rInf.OnWin() ?
283                 (KSHORT)rInf.GetOpt().GetPostItsWidth( rInf.GetOut() ) : 0;
284 }
285 
286 /*************************************************************************
287  *                 virtual SwPostItsPortion::Format()
288  *************************************************************************/
289 
290 sal_Bool SwPostItsPortion::Format( SwTxtFormatInfo &rInf )
291 {
292     sal_Bool bRet = SwLinePortion::Format( rInf );
293     // 32749: PostIts sollen keine Auswirkung auf Zeilenhoehe etc. haben
294     SetAscent( 1 );
295     Height( 1 );
296     return bRet;
297 }
298 
299 /*************************************************************************
300  *              virtual SwPostItsPortion::GetExpTxt()
301  *************************************************************************/
302 
303 sal_Bool SwPostItsPortion::GetExpTxt( const SwTxtSizeInfo &rInf,
304                                   XubString &rTxt ) const
305 {
306     if( rInf.OnWin() && rInf.GetOpt().IsPostIts() )
307         rTxt = ' ';
308     else
309         rTxt.Erase();
310     return sal_True;
311 }
312 
313