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