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