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