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 <com/sun/star/uno/Sequence.h> 29 #include <unotools/linguprops.hxx> 30 #include <unotools/lingucfg.hxx> 31 #include <hintids.hxx> 32 #include <sfx2/printer.hxx> 33 #include <editeng/hyznitem.hxx> 34 #include <editeng/escpitem.hxx> 35 #include <editeng/hngpnctitem.hxx> 36 #include <editeng/scriptspaceitem.hxx> 37 #include <editeng/brshitem.hxx> 38 #include <editeng/splwrap.hxx> 39 #include <editeng/pgrditem.hxx> 40 #include <editeng/tstpitem.hxx> 41 42 #include <SwSmartTagMgr.hxx> 43 #include <linguistic/lngprops.hxx> 44 #include <editeng/unolingu.hxx> 45 #include <breakit.hxx> 46 #include <editeng/forbiddenruleitem.hxx> 47 #include <txatbase.hxx> 48 #include <fmtinfmt.hxx> 49 #include <swmodule.hxx> 50 #include <vcl/svapp.hxx> 51 #include <vcl/wrkwin.hxx> 52 #include <viewsh.hxx> // ViewShell 53 #include <viewopt.hxx> // SwViewOptions 54 #include <frmtool.hxx> // DrawGraphic 55 #include <IDocumentSettingAccess.hxx> 56 #include <IDocumentDeviceAccess.hxx> 57 #include <paratr.hxx> // SwFmtDrop 58 #include <rootfrm.hxx> // SwRootFrm 59 #include <inftxt.hxx> // SwTxtInfo 60 #include <blink.hxx> // SwBlink 61 #include <noteurl.hxx> // SwNoteURL 62 #include <porftn.hxx> // SwFtnPortion 63 #include <porrst.hxx> // SwHangingPortion 64 #include <itratr.hxx> 65 #include <accessibilityoptions.hxx> 66 #include <wrong.hxx> 67 #include <doc.hxx> 68 #include <pam.hxx> 69 #include <SwGrammarMarkUp.hxx> 70 #include <cstdio> 71 #include <EnhancedPDFExportHelper.hxx> 72 73 //UUUU 74 #include <frmfmt.hxx> 75 76 #include <unomid.h> 77 78 using namespace ::com::sun::star; 79 using namespace ::com::sun::star::linguistic2; 80 using namespace ::com::sun::star::uno; 81 using namespace ::com::sun::star::beans; 82 83 84 #define CHAR_UNDERSCORE ((sal_Unicode)0x005F) 85 #define CHAR_LEFT_ARROW ((sal_Unicode)0x25C0) 86 #define CHAR_RIGHT_ARROW ((sal_Unicode)0x25B6) 87 #define CHAR_TAB ((sal_Unicode)0x2192) 88 #define CHAR_TAB_RTL ((sal_Unicode)0x2190) 89 #define CHAR_LINEBREAK ((sal_Unicode)0x21B5) 90 #define CHAR_LINEBREAK_RTL ((sal_Unicode)0x21B3) 91 92 #define DRAW_SPECIAL_OPTIONS_CENTER 1 93 #define DRAW_SPECIAL_OPTIONS_ROTATE 2 94 95 // --> OD 2006-06-27 #b6440955# 96 // variable moved to class <numfunc:GetDefBulletConfig> 97 //extern const sal_Char __FAR_DATA sBulletFntName[]; 98 namespace numfunc 99 { 100 extern const String& GetDefBulletFontname(); 101 extern bool IsDefBulletFontUserDefined(); 102 } 103 // <-- 104 105 #ifdef DBG_UTIL 106 // Test2: WYSIWYG++ 107 // Test4: WYSIWYG debug 108 static sal_Bool bDbgLow = sal_False; 109 #endif 110 111 #ifdef DBG_UTIL 112 113 sal_Bool SwTxtSizeInfo::IsOptCalm() const { return !GetOpt().IsTest3(); } 114 115 sal_Bool SwTxtSizeInfo::IsOptLow() const { return bDbgLow; } 116 117 sal_Bool SwTxtSizeInfo::IsOptDbg() const { return GetOpt().IsTest4(); } 118 119 sal_Bool SwTxtSizeInfo::IsOptTest1() const { return GetOpt().IsTest1(); } 120 121 sal_Bool SwTxtSizeInfo::IsOptTest2() const { return GetOpt().IsTest2(); } 122 123 sal_Bool SwTxtSizeInfo::IsOptTest3() const { return GetOpt().IsTest3(); } 124 125 sal_Bool SwTxtSizeInfo::IsOptTest4() const { return GetOpt().IsTest4(); } 126 127 sal_Bool SwTxtSizeInfo::IsOptTest5() const { return GetOpt().IsTest5(); } 128 129 sal_Bool SwTxtSizeInfo::IsOptTest6() const { return GetOpt().IsTest6(); } 130 131 sal_Bool SwTxtSizeInfo::IsOptTest7() const { return GetOpt().IsTest7(); } 132 133 sal_Bool SwTxtSizeInfo::IsOptTest8() const { return GetOpt().IsTest8(); } 134 135 #endif 136 137 /************************************************************************* 138 * SwLineInfo::SwLineInfo() 139 *************************************************************************/ 140 141 // --> OD 2008-01-17 #newlistlevelattrs# 142 SwLineInfo::SwLineInfo() 143 : pRuler( 0 ), 144 pSpace( 0 ), 145 nVertAlign( 0 ), 146 nDefTabStop( 0 ), 147 bListTabStopIncluded( false ), 148 nListTabStopPosition( 0 ) 149 { 150 } 151 152 SwLineInfo::~SwLineInfo() 153 { 154 delete pRuler; 155 } 156 void SwLineInfo::CtorInitLineInfo( const SwAttrSet& rAttrSet, 157 const SwTxtNode& rTxtNode ) 158 // <-- 159 { 160 // --> OD 2008-01-17 #newlistlevelattrs# 161 // pRuler = &rAttrSet.GetTabStops(); 162 delete pRuler; 163 pRuler = new SvxTabStopItem( rAttrSet.GetTabStops() ); 164 if ( rTxtNode.GetListTabStopPosition( nListTabStopPosition ) ) 165 { 166 bListTabStopIncluded = true; 167 168 // insert the list tab stop into SvxTabItem instance <pRuler> 169 const SvxTabStop aListTabStop( nListTabStopPosition, 170 SVX_TAB_ADJUST_LEFT ); 171 pRuler->Insert( aListTabStop ); 172 173 // remove default tab stops, which are before the inserted list tab stop 174 for ( sal_uInt16 i = 0; i < pRuler->Count(); i++ ) 175 { 176 if ( (*pRuler)[i].GetTabPos() < nListTabStopPosition && 177 (*pRuler)[i].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT ) 178 { 179 pRuler->Remove(i); 180 continue; 181 } 182 } 183 } 184 // <-- 185 // --> OD 2008-02-15 #newlistlevelattrs# 186 if ( !rTxtNode.getIDocumentSettingAccess()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) ) 187 { 188 // remove default tab stop at position 0 189 for ( sal_uInt16 i = 0; i < pRuler->Count(); i++ ) 190 { 191 if ( (*pRuler)[i].GetTabPos() == 0 && 192 (*pRuler)[i].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT ) 193 { 194 pRuler->Remove(i); 195 break; 196 } 197 } 198 } 199 // <-- 200 pSpace = &rAttrSet.GetLineSpacing(); 201 nVertAlign = rAttrSet.GetParaVertAlign().GetValue(); 202 nDefTabStop = MSHRT_MAX; 203 } 204 205 /************************************************************************* 206 * SwTxtInfo::CtorInitTxtInfo() 207 *************************************************************************/ 208 209 void SwTxtInfo::CtorInitTxtInfo( SwTxtFrm *pFrm ) 210 { 211 pPara = pFrm->GetPara(); 212 nTxtStart = pFrm->GetOfst(); 213 if( !pPara ) 214 { 215 ASSERT( pPara, "+SwTxtInfo::CTOR: missing paragraph information" ); 216 pFrm->Format(); 217 pPara = pFrm->GetPara(); 218 } 219 } 220 221 SwTxtInfo::SwTxtInfo( const SwTxtInfo &rInf ) 222 : pPara( ((SwTxtInfo&)rInf).GetParaPortion() ), 223 nTxtStart( rInf.GetTxtStart() ) 224 { } 225 226 227 #ifdef DBG_UTIL 228 /************************************************************************* 229 * ChkOutDev() 230 *************************************************************************/ 231 232 void ChkOutDev( const SwTxtSizeInfo &rInf ) 233 { 234 if ( !rInf.GetVsh() ) 235 return; 236 237 const OutputDevice* pOut = rInf.GetOut(); 238 const OutputDevice* pRef = rInf.GetRefDev(); 239 ASSERT( pOut && pRef, "ChkOutDev: invalid output devices" ) 240 } 241 #endif // PRODUCT 242 243 244 inline xub_StrLen GetMinLen( const SwTxtSizeInfo &rInf ) 245 { 246 const xub_StrLen nInfLen = rInf.GetIdx() + rInf.GetLen(); 247 return Min( rInf.GetTxt().Len(), nInfLen ); 248 } 249 250 251 SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew ) 252 : SwTxtInfo( rNew ), 253 pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()), 254 pVsh(((SwTxtSizeInfo&)rNew).GetVsh()), 255 pOut(((SwTxtSizeInfo&)rNew).GetOut()), 256 pRef(((SwTxtSizeInfo&)rNew).GetRefDev()), 257 pFnt(((SwTxtSizeInfo&)rNew).GetFont()), 258 pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()), 259 pFrm(rNew.pFrm), 260 pOpt(&rNew.GetOpt()), 261 pTxt(&rNew.GetTxt()), 262 nIdx(rNew.GetIdx()), 263 nLen(rNew.GetLen()), 264 nKanaIdx( rNew.GetKanaIdx() ), 265 bOnWin( rNew.OnWin() ), 266 bNotEOL( rNew.NotEOL() ), 267 bURLNotify( rNew.URLNotify() ), 268 bStopUnderFlow( rNew.StopUnderFlow() ), 269 bFtnInside( rNew.IsFtnInside() ), 270 bOtherThanFtnInside( rNew.IsOtherThanFtnInside() ), 271 bMulti( rNew.IsMulti() ), 272 bFirstMulti( rNew.IsFirstMulti() ), 273 bRuby( rNew.IsRuby() ), 274 bHanging( rNew.IsHanging() ), 275 bScriptSpace( rNew.HasScriptSpace() ), 276 bForbiddenChars( rNew.HasForbiddenChars() ), 277 bSnapToGrid( rNew.SnapToGrid() ), 278 nDirection( rNew.GetDirection() ) 279 { 280 #ifdef DBG_UTIL 281 ChkOutDev( *this ); 282 #endif 283 } 284 285 void SwTxtSizeInfo::CtorInitTxtSizeInfo( SwTxtFrm *pFrame, SwFont *pNewFnt, 286 const xub_StrLen nNewIdx, const xub_StrLen nNewLen ) 287 { 288 pKanaComp = NULL; 289 nKanaIdx = 0; 290 pFrm = pFrame; 291 CtorInitTxtInfo( pFrm ); 292 const SwTxtNode *pNd = pFrm->GetTxtNode(); 293 pVsh = pFrm->getRootFrm()->GetCurrShell(); 294 295 // Get the output and reference device 296 if ( pVsh ) 297 { 298 pOut = pVsh->GetOut(); 299 pRef = &pVsh->GetRefDev(); 300 bOnWin = pVsh->GetWin() || OUTDEV_WINDOW == pOut->GetOutDevType(); 301 } 302 else 303 { 304 //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein. 305 if ( pNd->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) ) 306 { 307 //in Ermangelung eines Besseren kann hier ja wohl nur noch das 308 //AppWin genommen werden? 309 pOut = GetpApp()->GetDefaultDevice(); 310 } 311 else 312 pOut = pNd->getIDocumentDeviceAccess()->getPrinter( false ); 313 314 pRef = pOut; 315 } 316 317 #ifdef DBG_UTIL 318 ChkOutDev( *this ); 319 #endif 320 321 // Set default layout mode ( LTR or RTL ). 322 if ( pFrm->IsRightToLeft() ) 323 { 324 pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL ); 325 pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL ); 326 nDirection = DIR_RIGHT2LEFT; 327 } 328 else 329 { 330 pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG ); 331 pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG ); 332 nDirection = DIR_LEFT2RIGHT; 333 } 334 335 /* LanguageType eLang; 336 const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions(); 337 if ( SvtCTLOptions::NUMERALS_HINDI == rCTLOptions.GetCTLTextNumerals() ) 338 eLang = LANGUAGE_ARABIC_SAUDI_ARABIA; 339 else if ( SvtCTLOptions::NUMERALS_ARABIC == rCTLOptions.GetCTLTextNumerals() ) 340 eLang = LANGUAGE_ENGLISH; 341 else 342 eLang = (LanguageType)::GetAppLanguage(); 343 344 pOut->SetDigitLanguage( eLang ); 345 pRef->SetDigitLanguage( eLang );*/ 346 347 // 348 // The Options 349 // 350 pOpt = pVsh ? 351 pVsh->GetViewOptions() : 352 SW_MOD()->GetViewOption( pNd->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) ); //Options vom Module wg. StarONE 353 354 // bURLNotify wird gesetzt, wenn MakeGraphic dies vorbereitet 355 // TODO: Aufdr?seln 356 bURLNotify = pNoteURL && !bOnWin; 357 358 SetSnapToGrid( pNd->GetSwAttrSet().GetParaGrid().GetValue() && 359 pFrm->IsInDocBody() ); 360 361 pFnt = pNewFnt; 362 pUnderFnt = 0; 363 pTxt = &pNd->GetTxt(); 364 365 nIdx = nNewIdx; 366 nLen = nNewLen; 367 bNotEOL = sal_False; 368 bStopUnderFlow = bFtnInside = bOtherThanFtnInside = sal_False; 369 bMulti = bFirstMulti = bRuby = bHanging = bScriptSpace = 370 bForbiddenChars = sal_False; 371 372 SetLen( GetMinLen( *this ) ); 373 } 374 375 SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew, const XubString &rTxt, 376 const xub_StrLen nIndex, const xub_StrLen nLength ) 377 : SwTxtInfo( rNew ), 378 pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()), 379 pVsh(((SwTxtSizeInfo&)rNew).GetVsh()), 380 pOut(((SwTxtSizeInfo&)rNew).GetOut()), 381 pRef(((SwTxtSizeInfo&)rNew).GetRefDev()), 382 pFnt(((SwTxtSizeInfo&)rNew).GetFont()), 383 pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()), 384 pFrm( rNew.pFrm ), 385 pOpt(&rNew.GetOpt()), 386 pTxt(&rTxt), 387 nIdx(nIndex), 388 nLen(nLength), 389 nKanaIdx( rNew.GetKanaIdx() ), 390 bOnWin( rNew.OnWin() ), 391 bNotEOL( rNew.NotEOL() ), 392 bURLNotify( rNew.URLNotify() ), 393 bStopUnderFlow( rNew.StopUnderFlow() ), 394 bFtnInside( rNew.IsFtnInside() ), 395 bOtherThanFtnInside( rNew.IsOtherThanFtnInside() ), 396 bMulti( rNew.IsMulti() ), 397 bFirstMulti( rNew.IsFirstMulti() ), 398 bRuby( rNew.IsRuby() ), 399 bHanging( rNew.IsHanging() ), 400 bScriptSpace( rNew.HasScriptSpace() ), 401 bForbiddenChars( rNew.HasForbiddenChars() ), 402 bSnapToGrid( rNew.SnapToGrid() ), 403 nDirection( rNew.GetDirection() ) 404 { 405 #ifdef DBG_UTIL 406 ChkOutDev( *this ); 407 #endif 408 SetLen( GetMinLen( *this ) ); 409 } 410 411 /************************************************************************* 412 * SwTxtSizeInfo::SelectFont() 413 *************************************************************************/ 414 415 void SwTxtSizeInfo::SelectFont() 416 { 417 // 8731: Der Weg muss ueber ChgPhysFnt gehen, sonst geraet 418 // der FontMetricCache durcheinander. In diesem Fall steht pLastMet 419 // auf dem alten Wert. 420 // Falsch: GetOut()->SetFont( GetFont()->GetFnt() ); 421 GetFont()->Invalidate(); 422 GetFont()->ChgPhysFnt( pVsh, *GetOut() ); 423 } 424 425 /************************************************************************* 426 * SwTxtSizeInfo::NoteAnimation() 427 *************************************************************************/ 428 429 void SwTxtSizeInfo::NoteAnimation() const 430 { 431 if( OnWin() ) 432 SwRootFrm::FlushVout(); 433 434 ASSERT( pOut == pVsh->GetOut(), 435 "SwTxtSizeInfo::NoteAnimation() changed pOut" ) 436 } 437 438 /************************************************************************* 439 * SwTxtSizeInfo::GetTxtSize() 440 *************************************************************************/ 441 442 SwPosSize SwTxtSizeInfo::GetTxtSize( OutputDevice* pOutDev, 443 const SwScriptInfo* pSI, 444 const XubString& rTxt, 445 const xub_StrLen nIndex, 446 const xub_StrLen nLength, 447 const sal_uInt16 nComp ) const 448 { 449 SwDrawTextInfo aDrawInf( pVsh, *pOutDev, pSI, rTxt, nIndex, nLength ); 450 aDrawInf.SetFrm( pFrm ); 451 aDrawInf.SetFont( pFnt ); 452 aDrawInf.SetSnapToGrid( SnapToGrid() ); 453 aDrawInf.SetKanaComp( nComp ); 454 SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf ); 455 return aSize; 456 } 457 458 /************************************************************************* 459 * SwTxtSizeInfo::GetTxtSize() 460 *************************************************************************/ 461 462 SwPosSize SwTxtSizeInfo::GetTxtSize() const 463 { 464 const SwScriptInfo& rSI = 465 ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo(); 466 467 // in some cases, compression is not allowed or suppressed for 468 // performance reasons 469 sal_uInt16 nComp =( SW_CJK == GetFont()->GetActual() && 470 rSI.CountCompChg() && 471 ! IsMulti() ) ? 472 GetKanaComp() : 473 0 ; 474 475 SwDrawTextInfo aDrawInf( pVsh, *pOut, &rSI, *pTxt, nIdx, nLen ); 476 aDrawInf.SetFrm( pFrm ); 477 aDrawInf.SetFont( pFnt ); 478 aDrawInf.SetSnapToGrid( SnapToGrid() ); 479 aDrawInf.SetKanaComp( nComp ); 480 return pFnt->_GetTxtSize( aDrawInf ); 481 } 482 483 /************************************************************************* 484 * SwTxtSizeInfo::GetTxtSize() 485 *************************************************************************/ 486 487 void SwTxtSizeInfo::GetTxtSize( const SwScriptInfo* pSI, const xub_StrLen nIndex, 488 const xub_StrLen nLength, const sal_uInt16 nComp, 489 sal_uInt16& nMinSize, sal_uInt16& nMaxSizeDiff ) const 490 { 491 SwDrawTextInfo aDrawInf( pVsh, *pOut, pSI, *pTxt, nIndex, nLength ); 492 aDrawInf.SetFrm( pFrm ); 493 aDrawInf.SetFont( pFnt ); 494 aDrawInf.SetSnapToGrid( SnapToGrid() ); 495 aDrawInf.SetKanaComp( nComp ); 496 SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf ); 497 nMaxSizeDiff = (sal_uInt16)aDrawInf.GetKanaDiff(); 498 nMinSize = aSize.Width(); 499 } 500 501 /************************************************************************* 502 * SwTxtSizeInfo::GetTxtBreak() 503 *************************************************************************/ 504 505 xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth, 506 const xub_StrLen nMaxLen, 507 const sal_uInt16 nComp ) const 508 { 509 const SwScriptInfo& rScriptInfo = 510 ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo(); 511 512 ASSERT( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" ) 513 SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo, 514 *pTxt, GetIdx(), nMaxLen ); 515 aDrawInf.SetFrm( pFrm ); 516 aDrawInf.SetFont( pFnt ); 517 aDrawInf.SetSnapToGrid( SnapToGrid() ); 518 aDrawInf.SetKanaComp( nComp ); 519 aDrawInf.SetHyphPos( 0 ); 520 521 return pFnt->GetTxtBreak( aDrawInf, nLineWidth ); 522 } 523 524 /************************************************************************* 525 * SwTxtSizeInfo::GetTxtBreak() 526 *************************************************************************/ 527 528 xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth, 529 const xub_StrLen nMaxLen, 530 const sal_uInt16 nComp, 531 xub_StrLen& rExtraCharPos ) const 532 { 533 const SwScriptInfo& rScriptInfo = 534 ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo(); 535 536 ASSERT( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" ) 537 SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo, 538 *pTxt, GetIdx(), nMaxLen ); 539 aDrawInf.SetFrm( pFrm ); 540 aDrawInf.SetFont( pFnt ); 541 aDrawInf.SetSnapToGrid( SnapToGrid() ); 542 aDrawInf.SetKanaComp( nComp ); 543 aDrawInf.SetHyphPos( &rExtraCharPos ); 544 545 return pFnt->GetTxtBreak( aDrawInf, nLineWidth ); 546 } 547 548 /************************************************************************* 549 * SwTxtPaintInfo::CtorInitTxtPaintInfo() 550 *************************************************************************/ 551 552 void SwTxtPaintInfo::CtorInitTxtPaintInfo( SwTxtFrm *pFrame, const SwRect &rPaint ) 553 { 554 CtorInitTxtSizeInfo( pFrame ); 555 aTxtFly.CtorInitTxtFly( pFrame ), 556 aPaintRect = rPaint; 557 nSpaceIdx = 0; 558 pSpaceAdd = NULL; 559 pWrongList = NULL; 560 pGrammarCheckList = NULL; 561 pSmartTags = NULL; // SMARTTAGS 562 563 #ifndef DBG_UTIL 564 pBrushItem = 0; 565 #else 566 pBrushItem = ((SvxBrushItem*)-1); 567 #endif 568 } 569 570 SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf, const XubString &rTxt ) 571 : SwTxtSizeInfo( rInf, rTxt ), 572 pWrongList( rInf.GetpWrongList() ), 573 pGrammarCheckList( rInf.GetGrammarCheckList() ), 574 pSmartTags( rInf.GetSmartTags() ), // SMARTTAGS 575 pSpaceAdd( rInf.GetpSpaceAdd() ), 576 pBrushItem( rInf.GetBrushItem() ), 577 aTxtFly( *rInf.GetTxtFly() ), 578 aPos( rInf.GetPos() ), 579 aPaintRect( rInf.GetPaintRect() ), 580 nSpaceIdx( rInf.GetSpaceIdx() ) 581 { } 582 583 SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf ) 584 : SwTxtSizeInfo( rInf ), 585 pWrongList( rInf.GetpWrongList() ), 586 pGrammarCheckList( rInf.GetGrammarCheckList() ), 587 pSmartTags( rInf.GetSmartTags() ), // SMARTTAGS 588 pSpaceAdd( rInf.GetpSpaceAdd() ), 589 pBrushItem( rInf.GetBrushItem() ), 590 aTxtFly( *rInf.GetTxtFly() ), 591 aPos( rInf.GetPos() ), 592 aPaintRect( rInf.GetPaintRect() ), 593 nSpaceIdx( rInf.GetSpaceIdx() ) 594 { } 595 596 extern Color aGlobalRetoucheColor; 597 598 /************************************************************************* 599 * lcl_IsDarkBackground 600 * 601 * Returns if the current background color is dark. 602 *************************************************************************/ 603 604 sal_Bool lcl_IsDarkBackground( const SwTxtPaintInfo& rInf ) 605 { 606 const Color* pCol = rInf.GetFont()->GetBackColor(); 607 if( ! pCol || COL_TRANSPARENT == pCol->GetColor() ) 608 { 609 const SvxBrushItem* pItem; 610 SwRect aOrigBackRect; 611 612 //UUUU 613 FillAttributesPtr aFillAttributes; 614 615 /// OD 21.08.2002 616 /// consider, that [GetBackgroundBrush(...)] can set <pCol> 617 /// - see implementation in /core/layout/paintfrm.cxx 618 /// OD 21.08.2002 #99657# 619 /// There is a background color, if there is a background brush and 620 /// its color is *not* "no fill"/"auto fill". 621 if( rInf.GetTxtFrm()->GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, sal_False ) ) 622 { 623 if ( !pCol ) 624 pCol = &pItem->GetColor(); 625 626 /// OD 30.08.2002 #99657# 627 /// determined color <pCol> can be <COL_TRANSPARENT>. Thus, check it. 628 if ( pCol->GetColor() == COL_TRANSPARENT) 629 pCol = NULL; 630 } 631 else 632 pCol = NULL; 633 } 634 635 636 if( !pCol ) 637 pCol = &aGlobalRetoucheColor; 638 639 return pCol->IsDark(); 640 } 641 642 /************************************************************************* 643 * SwTxtPaintInfo::_DrawText() 644 *************************************************************************/ 645 646 void SwTxtPaintInfo::_DrawText( const XubString &rText, const SwLinePortion &rPor, 647 const xub_StrLen nStart, const xub_StrLen nLength, 648 const sal_Bool bKern, const sal_Bool bWrong, 649 const sal_Bool bSmartTag, 650 const sal_Bool bGrammarCheck ) // SMARTTAGS 651 { 652 if( !nLength ) 653 return; 654 655 if( GetFont()->IsBlink() && OnWin() && rPor.Width() ) 656 { 657 // check if accessibility options allow blinking portions: 658 const ViewShell* pSh = GetTxtFrm()->getRootFrm()->GetCurrShell(); 659 if ( pSh && ! pSh->GetAccessibilityOptions()->IsStopAnimatedText() && 660 ! pSh->IsPreView() ) 661 { 662 if( !pBlink ) 663 pBlink = new SwBlink(); 664 665 Point aPoint( aPos ); 666 667 if ( GetTxtFrm()->IsRightToLeft() ) 668 GetTxtFrm()->SwitchLTRtoRTL( aPoint ); 669 670 if ( TEXT_LAYOUT_BIDI_STRONG != GetOut()->GetLayoutMode() ) 671 aPoint.X() -= rPor.Width(); 672 673 if ( GetTxtFrm()->IsVertical() ) 674 GetTxtFrm()->SwitchHorizontalToVertical( aPoint ); 675 676 pBlink->Insert( aPoint, &rPor, GetTxtFrm(), pFnt->GetOrientation() ); 677 678 if( !pBlink->IsVisible() ) 679 return; 680 } 681 else 682 { 683 delete pBlink; 684 pBlink = NULL; 685 } 686 } 687 688 // The SwScriptInfo is useless if we are inside a field portion 689 SwScriptInfo* pSI = 0; 690 if ( ! rPor.InFldGrp() ) 691 pSI = &GetParaPortion()->GetScriptInfo(); 692 693 // in some cases, kana compression is not allowed or suppressed for 694 // performance reasons 695 sal_uInt16 nComp = 0; 696 if ( ! IsMulti() ) 697 nComp = GetKanaComp(); 698 699 sal_Bool bCfgIsAutoGrammar = sal_False; 700 SvtLinguConfig().GetProperty( C2U( UPN_IS_GRAMMAR_AUTO ) ) >>= bCfgIsAutoGrammar; 701 const sal_Bool bBullet = OnWin() && GetOpt().IsBlank() && IsNoSymbol(); 702 const sal_Bool bTmpWrong = bWrong && OnWin() && GetOpt().IsOnlineSpell(); 703 const sal_Bool bTmpGrammarCheck = bGrammarCheck && OnWin() && bCfgIsAutoGrammar && GetOpt().IsOnlineSpell(); 704 const sal_Bool bTmpSmart = bSmartTag && OnWin() && !GetOpt().IsPagePreview() && SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS 705 706 ASSERT( GetParaPortion(), "No paragraph!"); 707 SwDrawTextInfo aDrawInf( pFrm->getRootFrm()->GetCurrShell(), *pOut, pSI, rText, nStart, nLength, 708 rPor.Width(), bBullet ); 709 710 aDrawInf.SetLeft( GetPaintRect().Left() ); 711 aDrawInf.SetRight( GetPaintRect().Right() ); 712 aDrawInf.SetUnderFnt( pUnderFnt ); 713 714 const long nSpaceAdd = ( rPor.IsBlankPortion() || rPor.IsDropPortion() || 715 rPor.InNumberGrp() ) ? 0 : GetSpaceAdd(); 716 if ( nSpaceAdd ) 717 { 718 xub_StrLen nCharCnt; 719 // --> FME 2005-04-04 #i41860# Thai justified alignemt needs some 720 // additional information: 721 aDrawInf.SetNumberOfBlanks( rPor.InTxtGrp() ? 722 static_cast<const SwTxtPortion&>(rPor).GetSpaceCnt( *this, nCharCnt ) : 723 0 ); 724 // <-- 725 } 726 727 aDrawInf.SetSpace( nSpaceAdd ); 728 aDrawInf.SetKanaComp( nComp ); 729 730 // the font is used to identify the current script via nActual 731 aDrawInf.SetFont( pFnt ); 732 // the frame is used to identify the orientation 733 aDrawInf.SetFrm( GetTxtFrm() ); 734 // we have to know if the paragraph should snap to grid 735 aDrawInf.SetSnapToGrid( SnapToGrid() ); 736 // for underlining we must know when not to add extra space behind 737 // a character in justified mode 738 aDrawInf.SetSpaceStop( ! rPor.GetPortion() || 739 rPor.GetPortion()->InFixMargGrp() || 740 rPor.GetPortion()->IsHolePortion() ); 741 742 if( GetTxtFly()->IsOn() ) 743 { 744 // aPos muss als TopLeft vorliegen, weil die ClipRects sonst 745 // nicht berechnet werden koennen. 746 const Point aPoint( aPos.X(), aPos.Y() - rPor.GetAscent() ); 747 const Size aSize( rPor.Width(), rPor.Height() ); 748 aDrawInf.SetPos( aPoint ); 749 aDrawInf.SetSize( aSize ); 750 aDrawInf.SetAscent( rPor.GetAscent() ); 751 aDrawInf.SetKern( bKern ? rPor.Width() : 0 ); 752 aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL ); 753 aDrawInf.SetGrammarCheck( bTmpGrammarCheck ? pGrammarCheckList : NULL ); 754 aDrawInf.SetSmartTags( bTmpSmart ? pSmartTags : NULL ); // SMARTTAGS 755 GetTxtFly()->DrawTextOpaque( aDrawInf ); 756 } 757 else 758 { 759 aDrawInf.SetPos( aPos ); 760 if( bKern ) 761 pFnt->_DrawStretchText( aDrawInf ); 762 else 763 { 764 aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL ); 765 aDrawInf.SetGrammarCheck( bTmpGrammarCheck ? pGrammarCheckList : NULL ); 766 aDrawInf.SetSmartTags( bTmpSmart ? pSmartTags : NULL ); // SMARTTAGS 767 pFnt->_DrawText( aDrawInf ); 768 } 769 } 770 } 771 772 /************************************************************************* 773 * SwTxtPaintInfo::CalcRect() 774 *************************************************************************/ 775 776 void SwTxtPaintInfo::CalcRect( const SwLinePortion& rPor, 777 SwRect* pRect, SwRect* pIntersect ) const 778 { 779 Size aSize( rPor.Width(), rPor.Height() ); 780 if( rPor.IsHangingPortion() ) 781 aSize.Width() = ((SwHangingPortion&)rPor).GetInnerWidth(); 782 if( rPor.InSpaceGrp() && GetSpaceAdd() ) 783 { 784 SwTwips nAdd = rPor.CalcSpacing( GetSpaceAdd(), *this ); 785 if( rPor.InFldGrp() && GetSpaceAdd() < 0 && nAdd ) 786 nAdd += GetSpaceAdd() / SPACING_PRECISION_FACTOR; 787 aSize.Width() += nAdd; 788 } 789 790 Point aPoint; 791 792 if( IsRotated() ) 793 { 794 long nTmp = aSize.Width(); 795 aSize.Width() = aSize.Height(); 796 aSize.Height() = nTmp; 797 if ( 1 == GetDirection() ) 798 { 799 aPoint.A() = X() - rPor.GetAscent(); 800 aPoint.B() = Y() - aSize.Height(); 801 } 802 else 803 { 804 aPoint.A() = X() - rPor.Height() + rPor.GetAscent(); 805 aPoint.B() = Y(); 806 } 807 } 808 else 809 { 810 aPoint.A() = X(); 811 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 812 if ( GetTxtFrm()->IsVertLR() ) 813 aPoint.B() = Y() - rPor.Height() + rPor.GetAscent(); 814 else 815 aPoint.B() = Y() - rPor.GetAscent(); 816 } 817 818 // Adjust x coordinate if we are inside a bidi portion 819 const sal_Bool bFrmDir = GetTxtFrm()->IsRightToLeft(); 820 sal_Bool bCounterDir = ( ! bFrmDir && DIR_RIGHT2LEFT == GetDirection() ) || 821 ( bFrmDir && DIR_LEFT2RIGHT == GetDirection() ); 822 823 if ( bCounterDir ) 824 aPoint.A() -= aSize.Width(); 825 826 SwRect aRect( aPoint, aSize ); 827 828 if ( GetTxtFrm()->IsRightToLeft() ) 829 GetTxtFrm()->SwitchLTRtoRTL( aRect ); 830 831 if ( GetTxtFrm()->IsVertical() ) 832 GetTxtFrm()->SwitchHorizontalToVertical( aRect ); 833 834 if ( pRect ) 835 *pRect = aRect; 836 837 if( aRect.HasArea() && pIntersect ) 838 { 839 ::SwAlignRect( aRect, (ViewShell*)GetVsh() ); 840 841 if ( GetOut()->IsClipRegion() ) 842 { 843 SwRect aClip( GetOut()->GetClipRegion().GetBoundRect() ); 844 aRect.Intersection( aClip ); 845 } 846 847 *pIntersect = aRect; 848 } 849 } 850 851 /************************************************************************* 852 * lcl_DrawSpecial 853 * 854 * Draws a special portion, e.g., line break portion, tab portion. 855 * rPor - The portion 856 * rRect - The rectangle surrounding the character 857 * pCol - Specify a color for the character 858 * bCenter - Draw the character centered, otherwise left aligned 859 * bRotate - Rotate the character if character rotation is set 860 *************************************************************************/ 861 862 static void lcl_DrawSpecial( const SwTxtPaintInfo& rInf, const SwLinePortion& rPor, 863 SwRect& rRect, const Color* pCol, sal_Unicode cChar, 864 sal_uInt8 nOptions ) 865 { 866 sal_Bool bCenter = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_CENTER ); 867 sal_Bool bRotate = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_ROTATE ); 868 869 // rRect is given in absolute coordinates 870 if ( rInf.GetTxtFrm()->IsRightToLeft() ) 871 rInf.GetTxtFrm()->SwitchRTLtoLTR( rRect ); 872 if ( rInf.GetTxtFrm()->IsVertical() ) 873 rInf.GetTxtFrm()->SwitchVerticalToHorizontal( rRect ); 874 875 const SwFont* pOldFnt = rInf.GetFont(); 876 877 // Font is generated only once: 878 static SwFont* pFnt = 0; 879 if ( ! pFnt ) 880 { 881 pFnt = new SwFont( *pOldFnt ); 882 pFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() ); 883 pFnt->SetName( numfunc::GetDefBulletFontname(), pFnt->GetActual() ); 884 pFnt->SetStyleName( aEmptyStr, pFnt->GetActual() ); 885 pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() ); 886 } 887 888 // Some of the current values are set at the font: 889 if ( ! bRotate ) 890 pFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() ); 891 else 892 pFnt->SetVertical( pOldFnt->GetOrientation() ); 893 894 if ( pCol ) 895 pFnt->SetColor( *pCol ); 896 else 897 pFnt->SetColor( pOldFnt->GetColor() ); 898 899 Size aFontSize( 0, SPECIAL_FONT_HEIGHT ); 900 pFnt->SetSize( aFontSize, pFnt->GetActual() ); 901 902 ((SwTxtPaintInfo&)rInf).SetFont( pFnt ); 903 904 // The maximum width depends on the current orientation 905 const sal_uInt16 nDir = pFnt->GetOrientation( rInf.GetTxtFrm()->IsVertical() ); 906 SwTwips nMaxWidth = 0; 907 switch ( nDir ) 908 { 909 case 0 : 910 nMaxWidth = rRect.Width(); 911 break; 912 case 900 : 913 case 2700 : 914 nMaxWidth = rRect.Height(); 915 break; 916 default: 917 ASSERT( sal_False, "Unknown direction set at font" ) 918 break; 919 } 920 921 // check if char fits into rectangle 922 const XubString aTmp( cChar ); 923 aFontSize = rInf.GetTxtSize( aTmp ).SvLSize(); 924 while ( aFontSize.Width() > nMaxWidth ) 925 { 926 SwTwips nFactor = ( 100 * aFontSize.Width() ) / nMaxWidth; 927 const SwTwips nOldWidth = aFontSize.Width(); 928 929 // new height for font 930 const sal_uInt8 nAct = pFnt->GetActual(); 931 aFontSize.Height() = ( 100 * pFnt->GetSize( nAct ).Height() ) / nFactor; 932 aFontSize.Width() = ( 100 * pFnt->GetSize( nAct).Width() ) / nFactor; 933 934 if ( !aFontSize.Width() && !aFontSize.Height() ) 935 break; 936 937 pFnt->SetSize( aFontSize, nAct ); 938 939 aFontSize = rInf.GetTxtSize( aTmp ).SvLSize(); 940 941 if ( aFontSize.Width() >= nOldWidth ) 942 break; 943 } 944 945 const Point aOldPos( rInf.GetPos() ); 946 947 // adjust values so that tab is vertically and horizontally centered 948 SwTwips nX = rRect.Left(); 949 SwTwips nY = rRect.Top(); 950 switch ( nDir ) 951 { 952 case 0 : 953 if ( bCenter ) 954 nX += ( rRect.Width() - aFontSize.Width() ) / 2; 955 nY += ( rRect.Height() - aFontSize.Height() ) / 2 + rInf.GetAscent(); 956 break; 957 case 900 : 958 if ( bCenter ) 959 nX += ( rRect.Width() - aFontSize.Height() ) / 2 + rInf.GetAscent(); 960 nY += ( rRect.Height() + aFontSize.Width() ) / 2; 961 break; 962 case 2700 : 963 if ( bCenter ) 964 nX += ( rRect.Width() + aFontSize.Height() ) / 2 - rInf.GetAscent(); 965 nY += ( rRect.Height() - aFontSize.Width() ) / 2; 966 break; 967 } 968 969 Point aTmpPos( nX, nY ); 970 ((SwTxtPaintInfo&)rInf).SetPos( aTmpPos ); 971 sal_uInt16 nOldWidth = rPor.Width(); 972 ((SwLinePortion&)rPor).Width( (sal_uInt16)aFontSize.Width() ); 973 rInf.DrawText( aTmp, rPor ); 974 ((SwLinePortion&)rPor).Width( nOldWidth ); 975 ((SwTxtPaintInfo&)rInf).SetFont( (SwFont*)pOldFnt ); 976 ((SwTxtPaintInfo&)rInf).SetPos( aOldPos ); 977 } 978 979 /************************************************************************* 980 * SwTxtPaintInfo::DrawRect() 981 *************************************************************************/ 982 983 void SwTxtPaintInfo::DrawRect( const SwRect &rRect, sal_Bool bNoGraphic, 984 sal_Bool bRetouche ) const 985 { 986 if ( OnWin() || !bRetouche ) 987 { 988 if( aTxtFly.IsOn() ) 989 ((SwTxtPaintInfo*)this)->GetTxtFly()-> 990 DrawFlyRect( pOut, rRect, *this, bNoGraphic ); 991 else if ( bNoGraphic ) 992 pOut->DrawRect( rRect.SVRect() ); 993 else 994 { 995 if(pBrushItem != ((SvxBrushItem*)-1)) 996 { 997 ::DrawGraphic( pBrushItem, pOut, aItemRect, rRect ); 998 } 999 else 1000 { 1001 OSL_ENSURE(false, "DrawRect: Uninitialized BrushItem!" ); 1002 } 1003 } 1004 } 1005 } 1006 1007 /************************************************************************* 1008 * SwTxtPaintInfo::DrawTab() 1009 *************************************************************************/ 1010 1011 void SwTxtPaintInfo::DrawTab( const SwLinePortion &rPor ) const 1012 { 1013 if( OnWin() ) 1014 { 1015 SwRect aRect; 1016 CalcRect( rPor, &aRect ); 1017 1018 if ( ! aRect.HasArea() ) 1019 return; 1020 1021 const sal_Unicode cChar = GetTxtFrm()->IsRightToLeft() ? 1022 CHAR_TAB_RTL : CHAR_TAB; 1023 const sal_uInt8 nOptions = DRAW_SPECIAL_OPTIONS_CENTER | 1024 DRAW_SPECIAL_OPTIONS_ROTATE; 1025 lcl_DrawSpecial( *this, rPor, aRect, 0, cChar, nOptions ); 1026 } 1027 } 1028 1029 /************************************************************************* 1030 * SwTxtPaintInfo::DrawLineBreak() 1031 *************************************************************************/ 1032 1033 void SwTxtPaintInfo::DrawLineBreak( const SwLinePortion &rPor ) const 1034 { 1035 if( OnWin() ) 1036 { 1037 KSHORT nOldWidth = rPor.Width(); 1038 ((SwLinePortion&)rPor).Width( LINE_BREAK_WIDTH ); 1039 1040 SwRect aRect; 1041 CalcRect( rPor, &aRect ); 1042 1043 if( aRect.HasArea() ) 1044 { 1045 const sal_Unicode cChar = GetTxtFrm()->IsRightToLeft() ? 1046 CHAR_LINEBREAK_RTL : CHAR_LINEBREAK; 1047 const sal_uInt8 nOptions = 0; 1048 lcl_DrawSpecial( *this, rPor, aRect, 0, cChar, nOptions ); 1049 } 1050 1051 ((SwLinePortion&)rPor).Width( nOldWidth ); 1052 } 1053 } 1054 1055 1056 /************************************************************************* 1057 * SwTxtPaintInfo::DrawRedArrow() 1058 *************************************************************************/ 1059 1060 void SwTxtPaintInfo::DrawRedArrow( const SwLinePortion &rPor ) const 1061 { 1062 Size aSize( SPECIAL_FONT_HEIGHT, SPECIAL_FONT_HEIGHT ); 1063 SwRect aRect( ((SwArrowPortion&)rPor).GetPos(), aSize ); 1064 sal_Unicode cChar; 1065 if( ((SwArrowPortion&)rPor).IsLeft() ) 1066 { 1067 aRect.Pos().Y() += 20 - GetAscent(); 1068 aRect.Pos().X() += 20; 1069 if( aSize.Height() > rPor.Height() ) 1070 aRect.Height( rPor.Height() ); 1071 cChar = CHAR_LEFT_ARROW; 1072 } 1073 else 1074 { 1075 if( aSize.Height() > rPor.Height() ) 1076 aRect.Height( rPor.Height() ); 1077 aRect.Pos().Y() -= aRect.Height() + 20; 1078 aRect.Pos().X() -= aRect.Width() + 20; 1079 cChar = CHAR_RIGHT_ARROW; 1080 } 1081 1082 if ( GetTxtFrm()->IsVertical() ) 1083 GetTxtFrm()->SwitchHorizontalToVertical( aRect ); 1084 1085 Color aCol( COL_LIGHTRED ); 1086 1087 if( aRect.HasArea() ) 1088 { 1089 const sal_uInt8 nOptions = 0; 1090 lcl_DrawSpecial( *this, rPor, aRect, &aCol, cChar, nOptions ); 1091 } 1092 } 1093 1094 1095 /************************************************************************* 1096 * SwTxtPaintInfo::DrawPostIts() 1097 *************************************************************************/ 1098 1099 void SwTxtPaintInfo::DrawPostIts( const SwLinePortion&, sal_Bool bScript ) const 1100 { 1101 if( OnWin() && pOpt->IsPostIts() ) 1102 { 1103 Size aSize; 1104 Point aTmp; 1105 1106 const sal_uInt16 nPostItsWidth = pOpt->GetPostItsWidth( GetOut() ); 1107 const sal_uInt16 nFontHeight = pFnt->GetHeight( pVsh, *GetOut() ); 1108 const sal_uInt16 nFontAscent = pFnt->GetAscent( pVsh, *GetOut() ); 1109 1110 switch ( pFnt->GetOrientation( GetTxtFrm()->IsVertical() ) ) 1111 { 1112 case 0 : 1113 aSize.Width() = nPostItsWidth; 1114 aSize.Height() = nFontHeight; 1115 aTmp.X() = aPos.X(); 1116 aTmp.Y() = aPos.Y() - nFontAscent; 1117 break; 1118 case 900 : 1119 aSize.Height() = nPostItsWidth; 1120 aSize.Width() = nFontHeight; 1121 aTmp.X() = aPos.X() - nFontAscent; 1122 aTmp.Y() = aPos.Y(); 1123 break; 1124 case 2700 : 1125 aSize.Height() = nPostItsWidth; 1126 aSize.Width() = nFontHeight; 1127 aTmp.X() = aPos.X() - nFontHeight + 1128 nFontAscent; 1129 aTmp.Y() = aPos.Y(); 1130 break; 1131 } 1132 1133 SwRect aTmpRect( aTmp, aSize ); 1134 1135 if ( GetTxtFrm()->IsRightToLeft() ) 1136 GetTxtFrm()->SwitchLTRtoRTL( aTmpRect ); 1137 1138 if ( GetTxtFrm()->IsVertical() ) 1139 GetTxtFrm()->SwitchHorizontalToVertical( aTmpRect ); 1140 1141 const Rectangle aRect( aTmpRect.SVRect() ); 1142 pOpt->PaintPostIts( (OutputDevice*)GetOut(), aRect, bScript ); 1143 } 1144 } 1145 1146 void SwTxtPaintInfo::DrawCheckBox( const SwFieldFormPortion &rPor, bool checked) const 1147 { 1148 SwRect aIntersect; 1149 CalcRect( rPor, &aIntersect, 0 ); 1150 if ( aIntersect.HasArea() ) 1151 { 1152 if (OnWin() && SwViewOption::IsFieldShadings() && 1153 !GetOpt().IsPagePreview()) 1154 { 1155 OutputDevice* pOut_ = (OutputDevice*)GetOut(); 1156 pOut_->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); 1157 pOut_->SetFillColor( SwViewOption::GetFieldShadingsColor() ); 1158 pOut_->SetLineColor(); 1159 pOut_->DrawRect( aIntersect.SVRect() ); 1160 pOut_->Pop(); 1161 } 1162 const int delta=10; 1163 Rectangle r(aIntersect.Left()+delta, aIntersect.Top()+delta, aIntersect.Right()-delta, aIntersect.Bottom()-delta); 1164 pOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); 1165 pOut->SetLineColor( Color(0, 0, 0)); 1166 pOut->SetFillColor(); 1167 pOut->DrawRect( r ); 1168 if (checked) { 1169 pOut->DrawLine(r.TopLeft(), r.BottomRight()); 1170 pOut->DrawLine(r.TopRight(), r.BottomLeft()); 1171 } 1172 pOut->Pop(); 1173 } 1174 } 1175 /************************************************************************* 1176 * SwTxtPaintInfo::DrawBackGround() 1177 *************************************************************************/ 1178 void SwTxtPaintInfo::DrawBackground( const SwLinePortion &rPor ) const 1179 { 1180 ASSERT( OnWin(), "SwTxtPaintInfo::DrawBackground: printer pollution ?" ); 1181 1182 SwRect aIntersect; 1183 CalcRect( rPor, 0, &aIntersect ); 1184 1185 if ( aIntersect.HasArea() ) 1186 { 1187 OutputDevice* pTmpOut = (OutputDevice*)GetOut(); 1188 pTmpOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); 1189 1190 // For dark background we do not want to have a filled rectangle 1191 if ( GetVsh() && GetVsh()->GetWin() && lcl_IsDarkBackground( *this ) ) 1192 { 1193 pTmpOut->SetLineColor( SwViewOption::GetFontColor().GetColor() ); 1194 } 1195 else 1196 { 1197 pTmpOut->SetFillColor( SwViewOption::GetFieldShadingsColor() ); 1198 pTmpOut->SetLineColor(); 1199 } 1200 1201 DrawRect( aIntersect, sal_True ); 1202 pTmpOut->Pop(); 1203 } 1204 } 1205 1206 void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion &rPor ) const 1207 { 1208 { 1209 SwRect aIntersect; 1210 CalcRect( rPor, &aIntersect, 0 ); 1211 if(aIntersect.HasArea()) 1212 { 1213 SwTxtNode *pNd = pFrm->GetTxtNode(); 1214 const ::sw::mark::IMark* pFieldmark = NULL; 1215 if(pNd) 1216 { 1217 const SwDoc *doc=pNd->GetDoc(); 1218 if(doc) 1219 { 1220 SwIndex aIndex(pNd, GetIdx()); 1221 SwPosition aPosition(*pNd, aIndex); 1222 pFieldmark=doc->getIDocumentMarkAccess()->getFieldmarkFor(aPosition); 1223 } 1224 } 1225 bool bIsStartMark=(1==GetLen() && CH_TXT_ATR_FIELDSTART==GetTxt().GetChar(GetIdx())); 1226 if(pFieldmark) { 1227 OSL_TRACE("Found Fieldmark"); 1228 #if DEBUG 1229 rtl::OUString str = pFieldmark->ToString( ); 1230 fprintf( stderr, "%s\n", rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr( ) ); 1231 #endif 1232 } 1233 if(bIsStartMark) OSL_TRACE("Found StartMark"); 1234 if (OnWin() && (pFieldmark!=NULL || bIsStartMark) && 1235 SwViewOption::IsFieldShadings() && 1236 !GetOpt().IsPagePreview()) 1237 { 1238 OutputDevice* pOutDev = (OutputDevice*)GetOut(); 1239 pOutDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); 1240 pOutDev->SetFillColor( SwViewOption::GetFieldShadingsColor() ); 1241 pOutDev->SetLineColor( ); 1242 pOutDev->DrawRect( aIntersect.SVRect() ); 1243 pOutDev->Pop(); 1244 } 1245 } 1246 } 1247 if( !pFnt->GetBackColor() ) return; 1248 1249 ASSERT( pFnt->GetBackColor(), "DrawBackBrush: Lost Color" ); 1250 1251 SwRect aIntersect; 1252 CalcRect( rPor, 0, &aIntersect ); 1253 1254 if ( aIntersect.HasArea() ) 1255 { 1256 OutputDevice* pTmpOut = (OutputDevice*)GetOut(); 1257 1258 // --> FME 2004-06-24 #i16816# tagged pdf support 1259 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pTmpOut ); 1260 // <-- 1261 1262 pTmpOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); 1263 1264 pTmpOut->SetFillColor( *pFnt->GetBackColor() ); 1265 pTmpOut->SetLineColor(); 1266 1267 DrawRect( aIntersect, sal_True, sal_False ); 1268 1269 pTmpOut->Pop(); 1270 } 1271 } 1272 1273 /************************************************************************* 1274 * SwTxtPaintInfo::DrawViewOpt() 1275 *************************************************************************/ 1276 1277 void SwTxtPaintInfo::DrawViewOpt( const SwLinePortion &rPor, 1278 const MSHORT nWhich ) const 1279 { 1280 if( OnWin() && !IsMulti() ) 1281 { 1282 sal_Bool bDraw = sal_False; 1283 switch( nWhich ) 1284 { 1285 case POR_FTN: 1286 case POR_QUOVADIS: 1287 case POR_NUMBER: 1288 case POR_FLD: 1289 case POR_URL: 1290 case POR_HIDDEN: 1291 case POR_TOX: 1292 case POR_REF: 1293 case POR_META: 1294 case POR_CONTROLCHAR: 1295 if ( !GetOpt().IsPagePreview() 1296 && !GetOpt().IsReadonly() 1297 && SwViewOption::IsFieldShadings() 1298 && ( POR_NUMBER != nWhich 1299 || pFrm->GetTxtNode()->HasMarkedLabel())) // #i27615# 1300 { 1301 bDraw = sal_True; 1302 } 1303 break; 1304 case POR_INPUTFLD: 1305 // input field shading also in read-only mode 1306 if ( !GetOpt().IsPagePreview() 1307 && SwViewOption::IsFieldShadings() ) 1308 { 1309 bDraw = sal_True; 1310 } 1311 break; 1312 case POR_TAB: if ( GetOpt().IsTab() ) bDraw = sal_True; break; 1313 case POR_SOFTHYPH: if ( GetOpt().IsSoftHyph() )bDraw = sal_True; break; 1314 case POR_BLANK: if ( GetOpt().IsHardBlank())bDraw = sal_True; break; 1315 default: 1316 { 1317 ASSERT( !this, "SwTxtPaintInfo::DrawViewOpt: don't know how to draw this" ); 1318 break; 1319 } 1320 } 1321 if ( bDraw ) 1322 DrawBackground( rPor ); 1323 } 1324 } 1325 1326 /************************************************************************* 1327 * SwTxtPaintInfo::_NotifyURL() 1328 *************************************************************************/ 1329 1330 void SwTxtPaintInfo::_NotifyURL( const SwLinePortion &rPor ) const 1331 { 1332 ASSERT( pNoteURL, "NotifyURL: pNoteURL gone with the wind!" ); 1333 1334 SwRect aIntersect; 1335 CalcRect( rPor, 0, &aIntersect ); 1336 1337 if( aIntersect.HasArea() ) 1338 { 1339 SwTxtNode *pNd = (SwTxtNode*)GetTxtFrm()->GetTxtNode(); 1340 SwTxtAttr *const pAttr = 1341 pNd->GetTxtAttrAt(GetIdx(), RES_TXTATR_INETFMT); 1342 if( pAttr ) 1343 { 1344 const SwFmtINetFmt& rFmt = pAttr->GetINetFmt(); 1345 pNoteURL->InsertURLNote( rFmt.GetValue(), rFmt.GetTargetFrame(), 1346 aIntersect ); 1347 } 1348 } 1349 } 1350 1351 /************************************************************************* 1352 * lcl_InitHyphValues() 1353 *************************************************************************/ 1354 1355 static void lcl_InitHyphValues( PropertyValues &rVals, 1356 sal_Int16 nMinLeading, sal_Int16 nMinTrailing ) 1357 { 1358 sal_Int32 nLen = rVals.getLength(); 1359 1360 if (0 == nLen) // yet to be initialized? 1361 { 1362 rVals.realloc( 2 ); 1363 PropertyValue *pVal = rVals.getArray(); 1364 1365 pVal[0].Name = C2U( UPN_HYPH_MIN_LEADING ); 1366 pVal[0].Handle = UPH_HYPH_MIN_LEADING; 1367 pVal[0].Value <<= nMinLeading; 1368 1369 pVal[1].Name = C2U( UPN_HYPH_MIN_TRAILING ); 1370 pVal[1].Handle = UPH_HYPH_MIN_TRAILING; 1371 pVal[1].Value <<= nMinTrailing; 1372 } 1373 else if (2 == nLen) // already initialized once? 1374 { 1375 PropertyValue *pVal = rVals.getArray(); 1376 pVal[0].Value <<= nMinLeading; 1377 pVal[1].Value <<= nMinTrailing; 1378 } 1379 else { 1380 DBG_ERROR( "unxpected size of sequence" ); 1381 } 1382 } 1383 1384 /************************************************************************* 1385 * SwTxtFormatInfo::GetHyphValues() 1386 *************************************************************************/ 1387 1388 const PropertyValues & SwTxtFormatInfo::GetHyphValues() const 1389 { 1390 DBG_ASSERT( 2 == aHyphVals.getLength(), 1391 "hyphenation values not yet initialized" ); 1392 return aHyphVals; 1393 } 1394 1395 /************************************************************************* 1396 * SwTxtFormatInfo::InitHyph() 1397 *************************************************************************/ 1398 1399 sal_Bool SwTxtFormatInfo::InitHyph( const sal_Bool bAutoHyphen ) 1400 { 1401 const SwAttrSet& rAttrSet = GetTxtFrm()->GetTxtNode()->GetSwAttrSet(); 1402 SetHanging( rAttrSet.GetHangingPunctuation().GetValue() ); 1403 SetScriptSpace( rAttrSet.GetScriptSpace().GetValue() ); 1404 SetForbiddenChars( rAttrSet.GetForbiddenRule().GetValue() ); 1405 const SvxHyphenZoneItem &rAttr = rAttrSet.GetHyphenZone(); 1406 MaxHyph() = rAttr.GetMaxHyphens(); 1407 sal_Bool bAuto = bAutoHyphen || rAttr.IsHyphen(); 1408 if( bAuto || bInterHyph ) 1409 { 1410 nHyphStart = nHyphWrdStart = STRING_LEN; 1411 nHyphWrdLen = 0; 1412 1413 const sal_Int16 nMinimalLeading = Max(rAttr.GetMinLead(), sal_uInt8(2)); 1414 const sal_Int16 nMinimalTrailing = rAttr.GetMinTrail(); 1415 lcl_InitHyphValues( aHyphVals, nMinimalLeading, nMinimalTrailing); 1416 } 1417 return bAuto; 1418 } 1419 1420 /************************************************************************* 1421 * SwTxtFormatInfo::CtorInitTxtFormatInfo() 1422 *************************************************************************/ 1423 1424 void SwTxtFormatInfo::CtorInitTxtFormatInfo( SwTxtFrm *pNewFrm, const sal_Bool bNewInterHyph, 1425 const sal_Bool bNewQuick, const sal_Bool bTst ) 1426 { 1427 CtorInitTxtPaintInfo( pNewFrm, SwRect() ); 1428 1429 bQuick = bNewQuick; 1430 bInterHyph = bNewInterHyph; 1431 1432 //! needs to be done in this order 1433 nMinLeading = 2; 1434 nMinTrailing = 2; 1435 nMinWordLength = 0; 1436 bAutoHyph = InitHyph(); 1437 1438 bIgnoreFly = sal_False; 1439 bFakeLineStart = sal_False; 1440 bShift = sal_False; 1441 bDropInit = sal_False; 1442 bTestFormat = bTst; 1443 nLeft = 0; 1444 nRight = 0; 1445 nFirst = 0; 1446 nRealWidth = 0; 1447 nForcedLeftMargin = 0; 1448 pRest = 0; 1449 nLineHeight = 0; 1450 nLineNettoHeight = 0; 1451 SetLineStart(0); 1452 Init(); 1453 } 1454 1455 /************************************************************************* 1456 * SwTxtFormatInfo::IsHyphenate() 1457 *************************************************************************/ 1458 // Trennen oder nicht trennen, das ist hier die Frage: 1459 // - in keinem Fall trennen, wenn der Hyphenator ERROR zurueckliefert, 1460 // oder wenn als Sprache NOLANGUAGE eingestellt ist. 1461 // - ansonsten immer trennen, wenn interaktive Trennung vorliegt 1462 // - wenn keine interakt. Trennung, dann nur trennen, wenn im ParaFmt 1463 // automatische Trennung eingestellt ist. 1464 1465 sal_Bool SwTxtFormatInfo::IsHyphenate() const 1466 { 1467 if( !bInterHyph && !bAutoHyph ) 1468 return sal_False; 1469 1470 LanguageType eTmp = GetFont()->GetLanguage(); 1471 if( LANGUAGE_DONTKNOW == eTmp || LANGUAGE_NONE == eTmp ) 1472 return sal_False; 1473 1474 uno::Reference< XHyphenator > xHyph = ::GetHyphenator(); 1475 if (bInterHyph && xHyph.is()) 1476 SvxSpellWrapper::CheckHyphLang( xHyph, eTmp ); 1477 1478 if( !xHyph.is() || !xHyph->hasLocale( pBreakIt->GetLocale(eTmp) ) ) 1479 return sal_False; 1480 return sal_True; 1481 } 1482 1483 /************************************************************************* 1484 * SwTxtFormatInfo::GetDropFmt() 1485 *************************************************************************/ 1486 1487 // Dropcaps vom SwTxtFormatter::CTOR gerufen. 1488 const SwFmtDrop *SwTxtFormatInfo::GetDropFmt() const 1489 { 1490 const SwFmtDrop *pDrop = &GetTxtFrm()->GetTxtNode()->GetSwAttrSet().GetDrop(); 1491 if( 1 >= pDrop->GetLines() || 1492 ( !pDrop->GetChars() && !pDrop->GetWholeWord() ) ) 1493 pDrop = 0; 1494 return pDrop; 1495 } 1496 1497 /************************************************************************* 1498 * SwTxtFormatInfo::Init() 1499 *************************************************************************/ 1500 1501 void SwTxtFormatInfo::Init() 1502 { 1503 // Nicht initialisieren: pRest, nLeft, nRight, nFirst, nRealWidth 1504 X(0); 1505 bArrowDone = bFull = bFtnDone = bErgoDone = bNumDone = bNoEndHyph = 1506 bNoMidHyph = bStop = bNewLine = bUnderFlow = sal_False; 1507 1508 // generally we do not allow number portions in follows, except... 1509 if ( GetTxtFrm()->IsFollow() ) 1510 { 1511 const SwTxtFrm* pMaster = GetTxtFrm()->FindMaster(); 1512 const SwLinePortion* pTmpPara = pMaster->GetPara(); 1513 1514 // there is a master for this follow and the master does not have 1515 // any contents (especially it does not have a number portion) 1516 bNumDone = ! pTmpPara || 1517 ! ((SwParaPortion*)pTmpPara)->GetFirstPortion()->IsFlyPortion(); 1518 } 1519 1520 pRoot = 0; 1521 pLast = 0; 1522 pFly = 0; 1523 pLastFld = 0; 1524 pLastTab = 0; 1525 pUnderFlow = 0; 1526 cTabDecimal = 0; 1527 nWidth = nRealWidth; 1528 nForcedLeftMargin = 0; 1529 nSoftHyphPos = 0; 1530 nUnderScorePos = STRING_LEN; 1531 cHookChar = 0; 1532 SetIdx(0); 1533 SetLen( GetTxt().Len() ); 1534 SetPaintOfst(0); 1535 } 1536 1537 /*-----------------16.10.00 11:39------------------- 1538 * There are a few differences between a copy constructor 1539 * and the following constructor for multi-line formatting. 1540 * The root is the first line inside the multi-portion, 1541 * the line start is the actual position in the text, 1542 * the line width is the rest width from the surrounding line 1543 * and the bMulti and bFirstMulti-flag has to be set correctly. 1544 * --------------------------------------------------*/ 1545 1546 SwTxtFormatInfo::SwTxtFormatInfo( const SwTxtFormatInfo& rInf, 1547 SwLineLayout& rLay, SwTwips nActWidth ) : SwTxtPaintInfo( rInf ) 1548 { 1549 pRoot = &rLay; 1550 pLast = &rLay; 1551 pFly = NULL; 1552 pLastFld = NULL; 1553 pUnderFlow = NULL; 1554 pRest = NULL; 1555 pLastTab = NULL; 1556 1557 nSoftHyphPos = 0; 1558 nUnderScorePos = STRING_LEN; 1559 nHyphStart = 0; 1560 nHyphWrdStart = 0; 1561 nHyphWrdLen = 0; 1562 nLineStart = rInf.GetIdx(); 1563 nLeft = rInf.nLeft; 1564 nRight = rInf.nRight; 1565 nFirst = rInf.nLeft; 1566 nRealWidth = KSHORT(nActWidth); 1567 nWidth = nRealWidth; 1568 nLineHeight = 0; 1569 nLineNettoHeight = 0; 1570 nForcedLeftMargin = 0; 1571 1572 nMinLeading = 0; 1573 nMinTrailing = 0; 1574 nMinWordLength = 0; 1575 bFull = sal_False; 1576 bFtnDone = sal_True; 1577 bErgoDone = sal_True; 1578 bNumDone = sal_True; 1579 bArrowDone = sal_True; 1580 bStop = sal_False; 1581 bNewLine = sal_True; 1582 bShift = sal_False; 1583 bUnderFlow = sal_False; 1584 bInterHyph = sal_False; 1585 bAutoHyph = sal_False; 1586 bDropInit = sal_False; 1587 bQuick = rInf.bQuick; 1588 bNoEndHyph = sal_False; 1589 bNoMidHyph = sal_False; 1590 bIgnoreFly = sal_False; 1591 bFakeLineStart = sal_False; 1592 1593 cTabDecimal = 0; 1594 cHookChar = 0; 1595 nMaxHyph = 0; 1596 bTestFormat = rInf.bTestFormat; 1597 SetMulti( sal_True ); 1598 SetFirstMulti( rInf.IsFirstMulti() ); 1599 } 1600 1601 /************************************************************************* 1602 * SwTxtFormatInfo::_CheckFtnPortion() 1603 *************************************************************************/ 1604 1605 sal_Bool SwTxtFormatInfo::_CheckFtnPortion( SwLineLayout* pCurr ) 1606 { 1607 KSHORT nHeight = pCurr->GetRealHeight(); 1608 SwLinePortion *pPor = pCurr->GetPortion(); 1609 sal_Bool bRet = sal_False; 1610 while( pPor ) 1611 { 1612 if( pPor->IsFtnPortion() && nHeight > ((SwFtnPortion*)pPor)->Orig() ) 1613 { 1614 bRet = sal_True; 1615 SetLineHeight( nHeight ); 1616 SetLineNettoHeight( pCurr->Height() ); 1617 break; 1618 } 1619 pPor = pPor->GetPortion(); 1620 } 1621 return bRet; 1622 } 1623 1624 1625 1626 1627 /************************************************************************* 1628 * SwTxtFormatInfo::ScanPortionEnd() 1629 *************************************************************************/ 1630 xub_StrLen SwTxtFormatInfo::ScanPortionEnd( const xub_StrLen nStart, 1631 const xub_StrLen nEnd ) 1632 { 1633 cHookChar = 0; 1634 xub_StrLen i = nStart; 1635 1636 // 1637 // Used for decimal tab handling: 1638 // 1639 const xub_Unicode cTabDec = GetLastTab() ? (sal_Unicode)GetTabDecimal() : 0; 1640 const xub_Unicode cThousandSep = ',' == cTabDec ? '.' : ','; 1641 // --> FME 2006-01-23 #i45951# German (Switzerland) uses ' as thousand separator: 1642 const xub_Unicode cThousandSep2 = ',' == cTabDec ? '.' : '\''; 1643 // <-- 1644 1645 bool bNumFound = false; 1646 const bool bTabCompat = GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT); 1647 1648 // Removed for i7288. bSkip used to be passed from SwFldPortion::Format 1649 // as IsFollow(). Therefore more than one special character was not 1650 // handled correctly at the beginning of follow fields. 1651 // if ( bSkip && i < nEnd ) 1652 // ++i; 1653 1654 for( ; i < nEnd; ++i ) 1655 { 1656 const xub_Unicode cPos = GetChar( i ); 1657 switch( cPos ) 1658 { 1659 case CH_TXTATR_BREAKWORD: 1660 case CH_TXTATR_INWORD: 1661 if( !HasHint( i )) 1662 break; 1663 // no break; 1664 1665 case CHAR_SOFTHYPHEN: 1666 case CHAR_HARDHYPHEN: 1667 case CHAR_HARDBLANK: 1668 case CH_TAB: 1669 case CH_BREAK: 1670 case CHAR_ZWSP : 1671 case CHAR_ZWNBSP : 1672 // case CHAR_RLM : 1673 // case CHAR_LRM : 1674 cHookChar = cPos; 1675 return i; 1676 1677 case CHAR_UNDERSCORE: 1678 if ( STRING_LEN == nUnderScorePos ) 1679 nUnderScorePos = i; 1680 break; 1681 1682 default: 1683 if ( cTabDec ) 1684 { 1685 if( cTabDec == cPos ) 1686 { 1687 ASSERT( cPos, "Unexpected end of string" ); 1688 if( cPos ) // robust 1689 { 1690 cHookChar = cPos; 1691 return i; 1692 } 1693 } 1694 1695 // 1696 // Compatibility: First non-digit character behind a 1697 // a digit character becomes the hook character 1698 // 1699 if ( bTabCompat ) 1700 { 1701 if ( ( 0x2F < cPos && cPos < 0x3A ) || 1702 ( bNumFound && ( cPos == cThousandSep || cPos == cThousandSep2 ) ) ) 1703 { 1704 bNumFound = true; 1705 } 1706 else 1707 { 1708 if ( bNumFound ) 1709 { 1710 cHookChar = cPos; 1711 SetTabDecimal( cPos ); 1712 return i; 1713 } 1714 } 1715 } 1716 } 1717 } 1718 } 1719 1720 // --> FME 2006-01-13 #130210# Check if character *behind* the portion has 1721 // to become the hook: 1722 if ( i == nEnd && i < GetTxt().Len() && bNumFound ) 1723 { 1724 const xub_Unicode cPos = GetChar( i ); 1725 if ( cPos != cTabDec && cPos != cThousandSep && cPos !=cThousandSep2 && ( 0x2F >= cPos || cPos >= 0x3A ) ) 1726 { 1727 cHookChar = GetChar( i ); 1728 SetTabDecimal( cHookChar ); 1729 } 1730 } 1731 1732 return i; 1733 } 1734 1735 sal_Bool SwTxtFormatInfo::LastKernPortion() 1736 { 1737 if( GetLast() ) 1738 { 1739 if( GetLast()->IsKernPortion() ) 1740 return sal_True; 1741 if( GetLast()->Width() || ( GetLast()->GetLen() && 1742 !GetLast()->IsHolePortion() ) ) 1743 return sal_False; 1744 } 1745 SwLinePortion* pPor = GetRoot(); 1746 SwLinePortion *pKern = NULL; 1747 while( pPor ) 1748 { 1749 if( pPor->IsKernPortion() ) 1750 pKern = pPor; 1751 else if( pPor->Width() || ( pPor->GetLen() && !pPor->IsHolePortion() ) ) 1752 pKern = NULL; 1753 pPor = pPor->GetPortion(); 1754 } 1755 if( pKern ) 1756 { 1757 SetLast( pKern ); 1758 return sal_True; 1759 } 1760 return sal_False; 1761 } 1762 1763 /************************************************************************* 1764 * class SwTxtSlot 1765 *************************************************************************/ 1766 1767 SwTxtSlot::SwTxtSlot( 1768 const SwTxtSizeInfo *pNew, 1769 const SwLinePortion *pPor, 1770 bool bTxtLen, 1771 bool bExgLists, 1772 const sal_Char *pCh ) 1773 : pOldTxt( 0 ), 1774 pOldSmartTagList( 0 ), 1775 pOldGrammarCheckList( 0 ), 1776 pTempList( 0 ) 1777 { 1778 if( pCh ) 1779 { 1780 aTxt = XubString( pCh, RTL_TEXTENCODING_MS_1252 ); 1781 bOn = sal_True; 1782 } 1783 else 1784 bOn = pPor->GetExpTxt( *pNew, aTxt ); 1785 1786 // Der Text wird ausgetauscht... 1787 if( bOn ) 1788 { 1789 pInf = (SwTxtSizeInfo*)pNew; 1790 nIdx = pInf->GetIdx(); 1791 nLen = pInf->GetLen(); 1792 pOldTxt = &(pInf->GetTxt()); 1793 pInf->SetTxt( aTxt ); 1794 pInf->SetIdx( 0 ); 1795 pInf->SetLen( bTxtLen ? pInf->GetTxt().Len() : pPor->GetLen() ); 1796 1797 // ST2 1798 if ( bExgLists ) 1799 { 1800 pOldSmartTagList = static_cast<SwTxtPaintInfo*>(pInf)->GetSmartTags(); 1801 if ( pOldSmartTagList ) 1802 { 1803 const sal_uInt16 nPos = pOldSmartTagList->GetWrongPos(nIdx); 1804 const xub_StrLen nListPos = pOldSmartTagList->Pos(nPos); 1805 if( nListPos == nIdx ) 1806 ((SwTxtPaintInfo*)pInf)->SetSmartTags( pOldSmartTagList->SubList( nPos ) ); 1807 else if( !pTempList && nPos < pOldSmartTagList->Count() && nListPos < nIdx && aTxt.Len() ) 1808 { 1809 pTempList = new SwWrongList( WRONGLIST_SMARTTAG ); 1810 pTempList->Insert( rtl::OUString(), 0, 0, aTxt.Len(), 0 ); 1811 ((SwTxtPaintInfo*)pInf)->SetSmartTags( pTempList ); 1812 } 1813 else 1814 ((SwTxtPaintInfo*)pInf)->SetSmartTags( 0); 1815 } 1816 pOldGrammarCheckList = static_cast<SwTxtPaintInfo*>(pInf)->GetGrammarCheckList(); 1817 if ( pOldGrammarCheckList ) 1818 { 1819 const sal_uInt16 nPos = pOldGrammarCheckList->GetWrongPos(nIdx); 1820 const xub_StrLen nListPos = pOldGrammarCheckList->Pos(nPos); 1821 if( nListPos == nIdx ) 1822 ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pOldGrammarCheckList->SubList( nPos ) ); 1823 else if( !pTempList && nPos < pOldGrammarCheckList->Count() && nListPos < nIdx && aTxt.Len() ) 1824 { 1825 pTempList = new SwWrongList( WRONGLIST_GRAMMAR ); 1826 pTempList->Insert( rtl::OUString(), 0, 0, aTxt.Len(), 0 ); 1827 ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pTempList ); 1828 } 1829 else 1830 ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( 0); 1831 } 1832 } 1833 } 1834 } 1835 1836 /************************************************************************* 1837 * SwTxtSlot::~SwTxtSlot() 1838 *************************************************************************/ 1839 1840 SwTxtSlot::~SwTxtSlot() 1841 { 1842 if( bOn ) 1843 { 1844 pInf->SetTxt( *pOldTxt ); 1845 pInf->SetIdx( nIdx ); 1846 pInf->SetLen( nLen ); 1847 1848 // ST2 1849 // Restore old smart tag list 1850 if ( pOldSmartTagList ) 1851 ((SwTxtPaintInfo*)pInf)->SetSmartTags( pOldSmartTagList ); 1852 if ( pOldGrammarCheckList ) 1853 ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pOldGrammarCheckList ); 1854 delete pTempList; 1855 } 1856 } 1857 1858 /************************************************************************* 1859 * SwFontSave::SwFontSave() 1860 *************************************************************************/ 1861 1862 SwFontSave::SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pNew, 1863 SwAttrIter* pItr ) 1864 : pFnt( pNew ? ((SwTxtSizeInfo&)rInf).GetFont() : 0 ) 1865 { 1866 if( pFnt ) 1867 { 1868 pInf = &((SwTxtSizeInfo&)rInf); 1869 // In these cases we temporarily switch to the new font: 1870 // 1. the fonts have a different magic number 1871 // 2. they have different script types 1872 // 3. their background colors differ (this is not covered by 1.) 1873 if( pFnt->DifferentMagic( pNew, pFnt->GetActual() ) || 1874 pNew->GetActual() != pFnt->GetActual() || 1875 ( ! pNew->GetBackColor() && pFnt->GetBackColor() ) || 1876 ( pNew->GetBackColor() && ! pFnt->GetBackColor() ) || 1877 ( pNew->GetBackColor() && pFnt->GetBackColor() && 1878 ( *pNew->GetBackColor() != *pFnt->GetBackColor() ) ) ) 1879 { 1880 pNew->SetTransparent( sal_True ); 1881 pNew->SetAlign( ALIGN_BASELINE ); 1882 pInf->SetFont( pNew ); 1883 } 1884 else 1885 pFnt = 0; 1886 pNew->Invalidate(); 1887 pNew->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() ); 1888 if( pItr && pItr->GetFnt() == pFnt ) 1889 { 1890 pIter = pItr; 1891 pIter->SetFnt( pNew ); 1892 } 1893 else 1894 pIter = NULL; 1895 } 1896 } 1897 1898 /************************************************************************* 1899 * SwFontSave::~SwFontSave() 1900 *************************************************************************/ 1901 1902 SwFontSave::~SwFontSave() 1903 { 1904 if( pFnt ) 1905 { 1906 // SwFont zurueckstellen 1907 pFnt->Invalidate(); 1908 pInf->SetFont( pFnt ); 1909 if( pIter ) 1910 { 1911 pIter->SetFnt( pFnt ); 1912 pIter->nPos = STRING_LEN; 1913 } 1914 } 1915 } 1916 1917 /************************************************************************* 1918 * SwDefFontSave::SwDefFontSave() 1919 *************************************************************************/ 1920 1921 SwDefFontSave::SwDefFontSave( const SwTxtSizeInfo &rInf ) 1922 : pFnt( ((SwTxtSizeInfo&)rInf).GetFont() ) 1923 { 1924 const sal_Bool bTmpAlter = pFnt->GetFixKerning() || 1925 ( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet(pFnt->GetActual()) ) 1926 ; 1927 1928 const sal_Bool bFamily = bTmpAlter && 1929 pFnt->GetName( pFnt->GetActual() ) != numfunc::GetDefBulletFontname(); 1930 const sal_Bool bRotation = (sal_Bool)pFnt->GetOrientation() && 1931 ! rInf.GetTxtFrm()->IsVertical(); 1932 1933 if( bFamily || bRotation ) 1934 { 1935 pNewFnt = new SwFont( *pFnt ); 1936 1937 if ( bFamily ) 1938 { 1939 pNewFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() ); 1940 pNewFnt->SetName( numfunc::GetDefBulletFontname(), pFnt->GetActual() ); 1941 pNewFnt->SetStyleName( aEmptyStr, pFnt->GetActual() ); 1942 pNewFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() ); 1943 pNewFnt->SetFixKerning( 0 ); 1944 } 1945 1946 if ( bRotation ) 1947 pNewFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() ); 1948 1949 pInf = &((SwTxtSizeInfo&)rInf); 1950 pNewFnt->Invalidate(); 1951 pInf->SetFont( pNewFnt ); 1952 } 1953 else 1954 { 1955 pFnt = 0; 1956 pNewFnt = 0; 1957 } 1958 } 1959 1960 /************************************************************************* 1961 * SwDefFontSave::~SwDefFontSave() 1962 *************************************************************************/ 1963 1964 SwDefFontSave::~SwDefFontSave() 1965 { 1966 if( pFnt ) 1967 { 1968 delete pNewFnt; 1969 // SwFont zurueckstellen 1970 pFnt->Invalidate(); 1971 pInf->SetFont( pFnt ); 1972 } 1973 } 1974 1975 /************************************************************************* 1976 * SwTxtFormatInfo::ChgHyph() 1977 *************************************************************************/ 1978 1979 sal_Bool SwTxtFormatInfo::ChgHyph( const sal_Bool bNew ) 1980 { 1981 const sal_Bool bOld = bAutoHyph; 1982 if( bAutoHyph != bNew ) 1983 { 1984 bAutoHyph = bNew; 1985 InitHyph( bNew ); 1986 // 5744: Sprache am Hyphenator einstellen. 1987 if( pFnt ) 1988 pFnt->ChgPhysFnt( pVsh, *pOut ); 1989 } 1990 return bOld; 1991 } 1992 1993 1994