xref: /AOO41X/main/sw/source/core/text/porexp.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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