1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 32 #include <hintids.hxx> 33 34 #include <editeng/tstpitem.hxx> 35 #include <editeng/lrspitem.hxx> 36 #include <editeng/scripttypeitem.hxx> 37 #include <com/sun/star/i18n/ScriptType.hdl> 38 #include <txatbase.hxx> 39 #include <txtftn.hxx> 40 #include <fmtftn.hxx> 41 #include <editsh.hxx> 42 #include <edimp.hxx> // fuer MACROS 43 #include <doc.hxx> 44 #include <swundo.hxx> // fuer UNDO-Ids 45 #include <ndtxt.hxx> 46 #include <ftnidx.hxx> 47 #include <expfld.hxx> 48 #include <rootfrm.hxx> 49 #include <cntfrm.hxx> 50 #include <breakit.hxx> 51 #include <txtfld.hxx> 52 #include <fmtfld.hxx> 53 #include <crsskip.hxx> 54 #include <txtfrm.hxx> // SwTxtFrm 55 #include <scriptinfo.hxx> 56 #include <svl/ctloptions.hxx> 57 #include <charfmt.hxx> // #i27615# 58 #include <numrule.hxx> 59 60 61 /************************************* 62 * harte Formatierung (Attribute) 63 *************************************/ 64 65 // wenn Selektion groesser Max Nodes oder mehr als Max Selektionen 66 // => keine Attribute 67 const sal_uInt16& getMaxLookup() 68 { 69 static const sal_uInt16 nMaxLookup = 1000; 70 return nMaxLookup; 71 } 72 73 // --> OD 2008-01-16 #newlistlevelattrs# 74 sal_Bool SwEditShell::GetCurAttr( SfxItemSet& rSet, 75 const bool bMergeIndentValuesOfNumRule ) const 76 // <-- 77 { 78 if( GetCrsrCnt() > getMaxLookup() ) 79 { 80 rSet.InvalidateAllItems(); 81 return sal_False; 82 } 83 84 SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() ); 85 SfxItemSet *pSet = &rSet; 86 87 FOREACHPAM_START(this) 88 89 // #i27615# if the cursor is in front of the numbering label 90 // the attributes to get are those from the numbering format. 91 if (PCURCRSR->IsInFrontOfLabel()) 92 { 93 SwTxtNode * pTxtNd = 94 PCURCRSR->GetPoint()->nNode.GetNode().GetTxtNode(); 95 96 if (pTxtNd) 97 { 98 SwNumRule * pNumRule = pTxtNd->GetNumRule(); 99 100 if (pNumRule) 101 { 102 const String & aCharFmtName = 103 pNumRule->Get(static_cast<sal_uInt16>(pTxtNd->GetActualListLevel())).GetCharFmtName(); 104 SwCharFmt * pCharFmt = 105 GetDoc()->FindCharFmtByName(aCharFmtName); 106 107 if (pCharFmt) 108 rSet.Put(pCharFmt->GetAttrSet()); 109 } 110 } 111 112 continue; 113 } 114 115 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(), 116 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex(); 117 xub_StrLen nSttCnt = PCURCRSR->GetMark()->nContent.GetIndex(), 118 nEndCnt = PCURCRSR->GetPoint()->nContent.GetIndex(); 119 120 if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt )) 121 { 122 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp; 123 nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp; 124 } 125 126 if( nEndNd - nSttNd >= getMaxLookup() ) 127 { 128 rSet.ClearItem(); 129 rSet.InvalidateAllItems(); 130 return sal_False; 131 } 132 133 // beim 1.Node traegt der Node die Werte in den GetSet ein (Initial) 134 // alle weiteren Nodes werden zum GetSet zu gemergt 135 for( sal_uLong n = nSttNd; n <= nEndNd; ++n ) 136 { 137 SwNode* pNd = GetDoc()->GetNodes()[ n ]; 138 switch( pNd->GetNodeType() ) 139 { 140 case ND_TEXTNODE: 141 { 142 xub_StrLen nStt = n == nSttNd ? nSttCnt : 0, 143 nEnd = n == nEndNd ? nEndCnt 144 : ((SwTxtNode*)pNd)->GetTxt().Len(); 145 // --> OD 2008-01-16 #newlistlevelattrs# 146 ((SwTxtNode*)pNd)->GetAttr( *pSet, nStt, nEnd, 147 sal_False, sal_True, 148 bMergeIndentValuesOfNumRule ); 149 // <-- 150 } 151 break; 152 case ND_GRFNODE: 153 case ND_OLENODE: 154 ((SwCntntNode*)pNd)->GetAttr( *pSet ); 155 break; 156 157 default: 158 pNd = 0; 159 } 160 161 if( pNd ) 162 { 163 if( pSet != &rSet ) 164 rSet.MergeValues( aSet ); 165 166 if( aSet.Count() ) 167 aSet.ClearItem(); 168 } 169 pSet = &aSet; 170 } 171 172 FOREACHPAM_END() 173 174 return sal_True; 175 } 176 177 SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl() const 178 { 179 SwTxtFmtColl *pFmt = 0; 180 181 if ( GetCrsrCnt() > getMaxLookup() ) 182 return 0; 183 184 FOREACHPAM_START(this) 185 186 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(), 187 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex(); 188 xub_StrLen nSttCnt = PCURCRSR->GetMark()->nContent.GetIndex(), 189 nEndCnt = PCURCRSR->GetPoint()->nContent.GetIndex(); 190 191 if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt )) 192 { 193 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp; 194 nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp; 195 } 196 197 if( nEndNd - nSttNd >= getMaxLookup() ) 198 { 199 pFmt = 0; 200 break; 201 } 202 203 for( sal_uLong n = nSttNd; n <= nEndNd; ++n ) 204 { 205 SwNode* pNd = GetDoc()->GetNodes()[ n ]; 206 if( pNd->IsTxtNode() ) 207 { 208 if( !pFmt ) 209 pFmt = ((SwTxtNode*)pNd)->GetTxtColl(); 210 else if( pFmt == ((SwTxtNode*)pNd)->GetTxtColl() ) // ??? 211 break; 212 } 213 } 214 215 FOREACHPAM_END() 216 return pFmt; 217 } 218 219 220 221 sal_Bool SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn ) 222 { 223 // der Cursor muss auf dem akt. Fussnoten-Anker stehen: 224 SwPaM* pCrsr = GetCrsr(); 225 SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode(); 226 if( !pTxtNd ) 227 return sal_False; 228 229 SwTxtAttr *const pFtn = pTxtNd->GetTxtAttrForCharAt( 230 pCrsr->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN); 231 if( pFtn && pFillFtn ) 232 { 233 // Daten vom Attribut uebertragen 234 const SwFmtFtn &rFtn = ((SwTxtFtn*)pFtn)->GetFtn(); 235 pFillFtn->SetNumber( rFtn ); 236 pFillFtn->SetEndNote( rFtn.IsEndNote() ); 237 } 238 return 0 != pFtn; 239 } 240 241 242 bool SwEditShell::SetCurFtn( const SwFmtFtn& rFillFtn ) 243 { 244 bool bChgd = false; 245 StartAllAction(); 246 247 SwPaM* pCrsr = GetCrsr(), *pFirst = pCrsr; 248 do { 249 bChgd |= pDoc->SetCurFtn( *pCrsr, rFillFtn.GetNumStr(), 250 rFillFtn.GetNumber(), 251 rFillFtn.IsEndNote() ); 252 253 } while( pFirst != ( pCrsr = (SwPaM*)pCrsr->GetNext() )); 254 255 EndAllAction(); 256 return bChgd; 257 } 258 259 260 261 /*sal_uInt16 SwEditShell::GetFtnCnt( sal_Bool bEndNotes = sal_False ) const 262 { 263 const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs(); 264 sal_uInt16 nCnt = 0; 265 for ( sal_uInt16 i = 0; i < rIdxs.Count(); ++i ) 266 { 267 const SwFmtFtn &rFtn = rIdxs[i]->GetFtn(); 268 if ( bEndNotes == rFtn.IsEndNote() ) 269 nCnt++; 270 } 271 return nCnt; 272 } */ 273 274 275 bool SwEditShell::HasFtns( bool bEndNotes ) const 276 { 277 const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs(); 278 for ( sal_uInt16 i = 0; i < rIdxs.Count(); ++i ) 279 { 280 const SwFmtFtn &rFtn = rIdxs[i]->GetFtn(); 281 if ( bEndNotes == rFtn.IsEndNote() ) 282 return sal_True; 283 } 284 return sal_False; 285 } 286 287 288 // gebe Liste aller Fussnoten und deren Anfangstexte 289 sal_uInt16 SwEditShell::GetSeqFtnList( SwSeqFldList& rList, bool bEndNotes ) 290 { 291 if( rList.Count() ) 292 rList.Remove( 0, rList.Count() ); 293 294 sal_uInt16 n, nFtnCnt = pDoc->GetFtnIdxs().Count(); 295 SwTxtFtn* pTxtFtn; 296 for( n = 0; n < nFtnCnt; ++n ) 297 { 298 pTxtFtn = pDoc->GetFtnIdxs()[ n ]; 299 const SwFmtFtn& rFtn = pTxtFtn->GetFtn(); 300 if ( rFtn.IsEndNote() != bEndNotes ) 301 continue; 302 303 SwNodeIndex* pIdx = pTxtFtn->GetStartNode(); 304 if( pIdx ) 305 { 306 SwNodeIndex aIdx( *pIdx, 1 ); 307 SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode(); 308 if( !pTxtNd ) 309 pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx ); 310 311 if( pTxtNd ) 312 { 313 String sTxt( rFtn.GetViewNumStr( *pDoc )); 314 if( sTxt.Len() ) 315 sTxt += ' '; 316 sTxt += pTxtNd->GetExpandTxt( 0, USHRT_MAX ); 317 318 _SeqFldLstElem* pNew = new _SeqFldLstElem( sTxt, 319 pTxtFtn->GetSeqRefNo() ); 320 while( rList.InsertSort( pNew ) ) 321 pNew->sDlgEntry += ' '; 322 } 323 } 324 } 325 326 return rList.Count(); 327 } 328 329 330 // linken Rand ueber Objectleiste einstellen (aenhlich dem Stufen von 331 // Numerierungen) 332 sal_Bool SwEditShell::IsMoveLeftMargin( sal_Bool bRight, sal_Bool bModulus ) const 333 { 334 sal_Bool bRet = sal_True; 335 336 const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDoc()-> 337 GetDefault( RES_PARATR_TABSTOP ); 338 sal_uInt16 nDefDist = static_cast<sal_uInt16>(rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134); 339 if( !nDefDist ) 340 return sal_False; 341 342 FOREACHPAM_START(this) 343 344 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(), 345 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex(); 346 347 if( nSttNd > nEndNd ) 348 { 349 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp; 350 } 351 352 SwCntntNode* pCNd; 353 for( sal_uLong n = nSttNd; bRet && n <= nEndNd; ++n ) 354 if( 0 != ( pCNd = GetDoc()->GetNodes()[ n ]->GetTxtNode() )) 355 { 356 const SvxLRSpaceItem& rLS = (SvxLRSpaceItem&) 357 pCNd->GetAttr( RES_LR_SPACE ); 358 if( bRight ) 359 { 360 long nNext = rLS.GetTxtLeft() + nDefDist; 361 if( bModulus ) 362 nNext = ( nNext / nDefDist ) * nDefDist; 363 SwFrm* pFrm = pCNd->getLayoutFrm( GetLayout() ); 364 if ( pFrm ) 365 { 366 const sal_uInt16 nFrmWidth = static_cast<sal_uInt16>( pFrm->IsVertical() ? 367 pFrm->Frm().Height() : 368 pFrm->Frm().Width() ); 369 bRet = nFrmWidth > ( nNext + MM50 ); 370 } 371 else 372 bRet = sal_False; 373 } 374 } 375 376 if( !bRet ) 377 break; 378 379 FOREACHPAM_END() 380 return bRet; 381 } 382 383 void SwEditShell::MoveLeftMargin( sal_Bool bRight, sal_Bool bModulus ) 384 { 385 StartAllAction(); 386 StartUndo( UNDO_START ); 387 388 SwPaM* pCrsr = GetCrsr(); 389 if( pCrsr->GetNext() != pCrsr ) // Mehrfachselektion ? 390 { 391 SwPamRanges aRangeArr( *pCrsr ); 392 SwPaM aPam( *pCrsr->GetPoint() ); 393 for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n ) 394 GetDoc()->MoveLeftMargin( aRangeArr.SetPam( n, aPam ), 395 bRight, bModulus ); 396 } 397 else 398 GetDoc()->MoveLeftMargin( *pCrsr, bRight, bModulus ); 399 400 EndUndo( UNDO_END ); 401 EndAllAction(); 402 } 403 404 405 inline sal_uInt16 lcl_SetScriptFlags( sal_uInt16 nType ) 406 { 407 sal_uInt16 nRet; 408 switch( nType ) 409 { 410 case ::com::sun::star::i18n::ScriptType::LATIN: nRet = SCRIPTTYPE_LATIN; break; 411 case ::com::sun::star::i18n::ScriptType::ASIAN: nRet = SCRIPTTYPE_ASIAN; break; 412 case ::com::sun::star::i18n::ScriptType::COMPLEX: nRet = SCRIPTTYPE_COMPLEX; break; 413 default: nRet = 0; 414 } 415 return nRet; 416 } 417 418 sal_Bool lcl_IsNoEndTxtAttrAtPos( const SwTxtNode& rTNd, xub_StrLen nPos, 419 sal_uInt16 &rScrpt, sal_Bool bInSelection, sal_Bool bNum ) 420 { 421 sal_Bool bRet = sal_False; 422 const String& rTxt = rTNd.GetTxt(); 423 String sExp; 424 425 // consider numbering 426 if ( bNum ) 427 { 428 bRet = sal_False; 429 430 // --> OD 2008-03-19 #refactorlists# 431 if ( rTNd.IsInList() ) 432 { 433 ASSERT( rTNd.GetNumRule(), 434 "<lcl_IsNoEndTxtAttrAtPos(..)> - no list style found at text node. Serious defect -> please inform OD." ); 435 const SwNumRule* pNumRule = rTNd.GetNumRule(); 436 const SwNumFmt &rNumFmt = pNumRule->Get( static_cast<sal_uInt16>(rTNd.GetActualListLevel()) ); 437 if( SVX_NUM_BITMAP != rNumFmt.GetNumberingType() ) 438 { 439 if ( SVX_NUM_CHAR_SPECIAL == rNumFmt.GetNumberingType() ) 440 sExp = rNumFmt.GetBulletChar(); 441 else 442 sExp = rTNd.GetNumString(); 443 } 444 } 445 } 446 447 // and fields 448 if ( CH_TXTATR_BREAKWORD == rTxt.GetChar( nPos ) ) 449 { 450 const SwTxtAttr* const pAttr = rTNd.GetTxtAttrForCharAt( nPos ); 451 if (pAttr) 452 { 453 bRet = sal_True; // all other than fields can be 454 // defined as weak-script ? 455 if ( RES_TXTATR_FIELD == pAttr->Which() ) 456 { 457 const SwField* const pFld = pAttr->GetFld().GetFld(); 458 if (pFld) 459 { 460 sExp += pFld->ExpandField(true); 461 } 462 } 463 } 464 } 465 466 xub_StrLen nEnd = sExp.Len(); 467 if ( nEnd ) 468 { 469 xub_StrLen n; 470 if( bInSelection ) 471 { 472 sal_uInt16 nScript; 473 for( n = 0; n < nEnd; n = (xub_StrLen) 474 pBreakIt->GetBreakIter()->endOfScript( sExp, n, nScript )) 475 { 476 nScript = pBreakIt->GetBreakIter()->getScriptType( sExp, n ); 477 rScrpt |= lcl_SetScriptFlags( nScript ); 478 } 479 } 480 else 481 rScrpt |= lcl_SetScriptFlags( pBreakIt->GetBreakIter()-> 482 getScriptType( sExp, nEnd-1 )); 483 } 484 485 return bRet; 486 } 487 488 489 // returns the scripttpye of the selection 490 sal_uInt16 SwEditShell::GetScriptType() const 491 { 492 sal_uInt16 nRet = 0; 493 //if( pBreakIt->GetBreakIter().is() ) 494 { 495 FOREACHPAM_START(this) 496 497 const SwPosition *pStt = PCURCRSR->Start(), 498 *pEnd = pStt == PCURCRSR->GetMark() 499 ? PCURCRSR->GetPoint() 500 : PCURCRSR->GetMark(); 501 if( pStt == pEnd || *pStt == *pEnd ) 502 { 503 const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode(); 504 if( pTNd ) 505 { 506 // try to get SwScriptInfo 507 const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd ); 508 509 xub_StrLen nPos = pStt->nContent.GetIndex(); 510 //Task 90448: we need the scripttype of the previous 511 // position, if no selection exist! 512 if( nPos ) 513 { 514 SwIndex aIdx( pStt->nContent ); 515 if( pTNd->GoPrevious( &aIdx, CRSR_SKIP_CHARS ) ) 516 nPos = aIdx.GetIndex(); 517 } 518 519 sal_uInt16 nScript; 520 521 if ( pTNd->GetTxt().Len() ) 522 { 523 nScript = pScriptInfo ? 524 pScriptInfo->ScriptType( nPos ) : 525 pBreakIt->GetBreakIter()->getScriptType( pTNd->GetTxt(), nPos ); 526 } 527 else 528 nScript = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() ); 529 530 if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nPos, nRet, sal_False, sal_False )) 531 nRet |= lcl_SetScriptFlags( nScript ); 532 } 533 } 534 else if ( pBreakIt->GetBreakIter().is() ) 535 { 536 sal_uLong nEndIdx = pEnd->nNode.GetIndex(); 537 SwNodeIndex aIdx( pStt->nNode ); 538 for( ; aIdx.GetIndex() <= nEndIdx; aIdx++ ) 539 if( aIdx.GetNode().IsTxtNode() ) 540 { 541 const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode(); 542 const String& rTxt = pTNd->GetTxt(); 543 544 // try to get SwScriptInfo 545 const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd ); 546 547 xub_StrLen nChg = aIdx == pStt->nNode 548 ? pStt->nContent.GetIndex() 549 : 0, 550 nEndPos = aIdx == nEndIdx 551 ? pEnd->nContent.GetIndex() 552 : rTxt.Len(); 553 554 ASSERT( nEndPos <= rTxt.Len(), "Index outside the range - endless loop!" ); 555 if( nEndPos > rTxt.Len() ) 556 nEndPos = rTxt.Len(); 557 558 sal_uInt16 nScript; 559 while( nChg < nEndPos ) 560 { 561 nScript = pScriptInfo ? 562 pScriptInfo->ScriptType( nChg ) : 563 pBreakIt->GetBreakIter()->getScriptType( 564 rTxt, nChg ); 565 566 if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nChg, nRet, sal_True, 567 0 == nChg && rTxt.Len() == nEndPos ) ) 568 nRet |= lcl_SetScriptFlags( nScript ); 569 570 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | 571 SCRIPTTYPE_COMPLEX) == nRet ) 572 break; 573 574 xub_StrLen nFldPos = nChg+1; 575 576 nChg = pScriptInfo ? 577 pScriptInfo->NextScriptChg( nChg ) : 578 (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( 579 rTxt, nChg, nScript ); 580 581 nFldPos = rTxt.Search( 582 CH_TXTATR_BREAKWORD, nFldPos ); 583 if( nFldPos < nChg ) 584 nChg = nFldPos; 585 } 586 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | 587 SCRIPTTYPE_COMPLEX) == nRet ) 588 break; 589 } 590 } 591 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | 592 SCRIPTTYPE_COMPLEX) == nRet ) 593 break; 594 595 FOREACHPAM_END() 596 } 597 if( !nRet ) 598 nRet = SvtLanguageOptions::GetScriptTypeOfLanguage( LANGUAGE_SYSTEM ); 599 return nRet; 600 } 601 602 603 sal_uInt16 SwEditShell::GetCurLang() const 604 { 605 const SwPaM* pCrsr = GetCrsr(); 606 const SwPosition& rPos = *pCrsr->GetPoint(); 607 const SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode(); 608 sal_uInt16 nLang; 609 if( pTNd ) 610 { 611 //JP 24.9.2001: if exist no selection, then get the language before 612 // the current character! 613 xub_StrLen nPos = rPos.nContent.GetIndex(); 614 if( nPos && !pCrsr->HasMark() ) 615 --nPos; 616 nLang = pTNd->GetLang( nPos ); 617 } 618 else 619 nLang = LANGUAGE_DONTKNOW; 620 return nLang; 621 } 622 623 sal_uInt16 SwEditShell::GetScalingOfSelectedText() const 624 { 625 const SwPaM* pCrsr = GetCrsr(); 626 const SwPosition* pStt = pCrsr->Start(); 627 const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode(); 628 ASSERT( pTNd, "no textnode available" ); 629 630 sal_uInt16 nScaleWidth; 631 if( pTNd ) 632 { 633 xub_StrLen nStt = pStt->nContent.GetIndex(), nEnd; 634 const SwPosition* pEnd = pStt == pCrsr->GetPoint() 635 ? pCrsr->GetMark() 636 : pCrsr->GetPoint(); 637 if( pStt->nNode == pEnd->nNode ) 638 nEnd = pEnd->nContent.GetIndex(); 639 else 640 nEnd = pTNd->GetTxt().Len(); 641 nScaleWidth = pTNd->GetScalingOfSelectedText( nStt, nEnd ); 642 } 643 else 644 nScaleWidth = 100; // default are no scaling -> 100% 645 return nScaleWidth; 646 } 647