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