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 #include <editeng/cmapitem.hxx> 30 31 #ifndef _OUTDEV_HXX //autogen 32 #include <vcl/outdev.hxx> 33 #endif 34 #ifndef _COM_SUN_STAR_I18N_CHARTYPE_HDL 35 #include <com/sun/star/i18n/CharType.hdl> 36 #endif 37 #ifndef _COM_SUN_STAR_I18N_WORDTYPE_HDL 38 #include <com/sun/star/i18n/WordType.hdl> 39 #endif 40 41 #ifndef _PRINT_HXX //autogen 42 #include <vcl/print.hxx> 43 #endif 44 #include <errhdl.hxx> 45 #include <fntcache.hxx> 46 #include <swfont.hxx> 47 #include <breakit.hxx> 48 #include <txtfrm.hxx> // SwTxtFrm 49 #include <scriptinfo.hxx> 50 51 using namespace ::com::sun::star::i18n; 52 53 54 #define KAPITAELCHENPROP 74 55 56 /************************************************************************* 57 * class SwCapitalInfo 58 * 59 * The information encapsulated in SwCapitalInfo is required 60 * by the ::Do functions. They contain the information about 61 * the original string, whereas rDo.GetInf() contains information 62 * about the display string. 63 *************************************************************************/ 64 65 class SwCapitalInfo 66 { 67 public: 68 explicit SwCapitalInfo( const XubString& rOrigText ) : 69 rString( rOrigText ), nIdx( 0 ), nLen( 0 ) {}; 70 const XubString& rString; 71 xub_StrLen nIdx; 72 xub_StrLen nLen; 73 }; 74 75 /************************************************************************* 76 * xub_StrLen lcl_CalcCaseMap() 77 * 78 * rFnt: required for CalcCaseMap 79 * rOrigString: The original string 80 * nOfst: Position of the substring in rOrigString 81 * nLen: Length if the substring in rOrigString 82 * nIdx: Referes to a position in the display string and should be mapped 83 * to a position in rOrigString 84 *************************************************************************/ 85 86 xub_StrLen lcl_CalcCaseMap( const SwFont& rFnt, 87 const XubString& rOrigString, 88 xub_StrLen nOfst, 89 xub_StrLen nLen, 90 xub_StrLen nIdx ) 91 { 92 int j = 0; 93 const xub_StrLen nEnd = nOfst + nLen; 94 ASSERT( nEnd <= rOrigString.Len(), "lcl_CalcCaseMap: Wrong parameters" ) 95 96 // special case for title case: 97 const bool bTitle = SVX_CASEMAP_TITEL == rFnt.GetCaseMap() && 98 pBreakIt->GetBreakIter().is(); 99 for ( xub_StrLen i = nOfst; i < nEnd; ++i ) 100 { 101 XubString aTmp( rOrigString, i, 1 ); 102 103 if ( !bTitle || 104 pBreakIt->GetBreakIter()->isBeginWord( 105 rOrigString, i, 106 pBreakIt->GetLocale( rFnt.GetLanguage() ), 107 WordType::ANYWORD_IGNOREWHITESPACES ) ) 108 aTmp = rFnt.GetActualFont().CalcCaseMap( aTmp ); 109 110 j += aTmp.Len(); 111 112 if ( j > nIdx ) 113 return i; 114 } 115 116 return nOfst + nLen; 117 } 118 119 /************************************************************************* 120 * class SwDoCapitals 121 *************************************************************************/ 122 123 class SwDoCapitals 124 { 125 protected: 126 SwDrawTextInfo &rInf; 127 SwCapitalInfo* pCapInf; // referes to additional information 128 // required by the ::Do function 129 public: 130 SwDoCapitals ( SwDrawTextInfo &rInfo ) : rInf( rInfo ), pCapInf( 0 ) { } 131 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) = 0; 132 virtual void Do() = 0; 133 inline OutputDevice& GetOut() { return rInf.GetOut(); } 134 inline SwDrawTextInfo& GetInf() { return rInf; } 135 inline SwCapitalInfo* GetCapInf() const { return pCapInf; } 136 inline void SetCapInf( SwCapitalInfo& rNew ) { pCapInf = &rNew; } 137 }; 138 139 /************************************************************************* 140 * class SwDoGetCapitalSize 141 *************************************************************************/ 142 143 class SwDoGetCapitalSize : public SwDoCapitals 144 { 145 protected: 146 Size aTxtSize; 147 public: 148 SwDoGetCapitalSize( SwDrawTextInfo &rInfo ) : SwDoCapitals ( rInfo ) { } 149 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); 150 virtual void Do(); 151 const Size &GetSize() const { return aTxtSize; } 152 }; 153 154 void SwDoGetCapitalSize::Init( SwFntObj *, SwFntObj * ) 155 { 156 aTxtSize.Height() = 0; 157 aTxtSize.Width() = 0; 158 } 159 160 void SwDoGetCapitalSize::Do() 161 { 162 aTxtSize.Width() += rInf.GetSize().Width(); 163 if( rInf.GetUpper() ) 164 aTxtSize.Height() = rInf.GetSize().Height(); 165 } 166 167 /************************************************************************* 168 * SwSubFont::GetCapitalSize() 169 *************************************************************************/ 170 171 Size SwSubFont::GetCapitalSize( SwDrawTextInfo& rInf ) 172 { 173 // Start: 174 const long nOldKern = rInf.GetKern(); 175 rInf.SetKern( CheckKerning() ); 176 Point aPos; 177 rInf.SetPos( aPos ); 178 rInf.SetSpace( 0 ); 179 rInf.SetDrawSpace( sal_False ); 180 SwDoGetCapitalSize aDo( rInf ); 181 DoOnCapitals( aDo ); 182 Size aTxtSize( aDo.GetSize() ); 183 184 // End: 185 if( !aTxtSize.Height() ) 186 { 187 SV_STAT( nGetTextSize ); 188 aTxtSize.Height() = short ( rInf.GetpOut()->GetTextHeight() ); 189 } 190 rInf.SetKern( nOldKern ); 191 return aTxtSize; 192 } 193 194 /************************************************************************* 195 * class SwDoGetCapitalBreak 196 *************************************************************************/ 197 198 class SwDoGetCapitalBreak : public SwDoCapitals 199 { 200 protected: 201 xub_StrLen *pExtraPos; 202 long nTxtWidth; 203 xub_StrLen nBreak; 204 public: 205 SwDoGetCapitalBreak( SwDrawTextInfo &rInfo, long nWidth, xub_StrLen *pExtra) 206 : SwDoCapitals ( rInfo ), pExtraPos( pExtra ), nTxtWidth( nWidth ), 207 nBreak( STRING_LEN ) 208 { } 209 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); 210 virtual void Do(); 211 xub_StrLen GetBreak() const { return nBreak; } 212 }; 213 214 void SwDoGetCapitalBreak::Init( SwFntObj *, SwFntObj * ) 215 { 216 } 217 218 void SwDoGetCapitalBreak::Do() 219 { 220 if ( nTxtWidth ) 221 { 222 if ( rInf.GetSize().Width() < nTxtWidth ) 223 nTxtWidth -= rInf.GetSize().Width(); 224 else 225 { 226 xub_StrLen nEnd = rInf.GetEnd(); 227 if( pExtraPos ) 228 { 229 nBreak = GetOut().GetTextBreak( rInf.GetText(), nTxtWidth, '-', 230 *pExtraPos, rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() ); 231 if( *pExtraPos > nEnd ) 232 *pExtraPos = nEnd; 233 } 234 else 235 nBreak = GetOut().GetTextBreak( rInf.GetText(), nTxtWidth, 236 rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() ); 237 238 if( nBreak > nEnd ) 239 nBreak = nEnd; 240 241 // nBreak may be relative to the display string. It has to be 242 // calculated relative to the original string: 243 if ( GetCapInf() ) 244 { 245 if ( GetCapInf()->nLen != rInf.GetLen() ) 246 nBreak = lcl_CalcCaseMap( *rInf.GetFont(), 247 GetCapInf()->rString, 248 GetCapInf()->nIdx, 249 GetCapInf()->nLen, nBreak ); 250 else 251 nBreak = nBreak + GetCapInf()->nIdx; 252 } 253 254 nTxtWidth = 0; 255 } 256 } 257 } 258 259 /************************************************************************* 260 * SwFont::GetCapitalBreak() 261 *************************************************************************/ 262 263 xub_StrLen SwFont::GetCapitalBreak( ViewShell* pSh, const OutputDevice* pOut, 264 const SwScriptInfo* pScript, const XubString& rTxt, long nTextWidth, 265 xub_StrLen *pExtra, const xub_StrLen nIdx, const xub_StrLen nLen ) 266 { 267 // Start: 268 Point aPos( 0, 0 ); 269 SwDrawTextInfo aInfo(pSh, *(OutputDevice*)pOut, pScript, rTxt, nIdx, nLen, 270 0, sal_False); 271 aInfo.SetPos( aPos ); 272 aInfo.SetSpace( 0 ); 273 aInfo.SetWrong( NULL ); 274 aInfo.SetGrammarCheck( NULL ); 275 aInfo.SetSmartTags( NULL ); // SMARTTAGS 276 aInfo.SetDrawSpace( sal_False ); 277 aInfo.SetKern( CheckKerning() ); 278 aInfo.SetKanaComp( pScript ? 0 : 100 ); 279 aInfo.SetFont( this ); 280 281 SwDoGetCapitalBreak aDo( aInfo, nTextWidth, pExtra ); 282 DoOnCapitals( aDo ); 283 return aDo.GetBreak(); 284 } 285 286 /************************************************************************* 287 * class SwDoDrawCapital 288 *************************************************************************/ 289 290 class SwDoDrawCapital : public SwDoCapitals 291 { 292 protected: 293 SwFntObj *pUpperFnt; 294 SwFntObj *pLowerFnt; 295 public: 296 SwDoDrawCapital( SwDrawTextInfo &rInfo ) : 297 SwDoCapitals( rInfo ) 298 { } 299 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); 300 virtual void Do(); 301 void DrawSpace( Point &rPos ); 302 }; 303 304 void SwDoDrawCapital::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) 305 { 306 pUpperFnt = pUpperFont; 307 pLowerFnt = pLowerFont; 308 } 309 310 void SwDoDrawCapital::Do() 311 { 312 SV_STAT( nDrawText ); 313 sal_uInt16 nOrgWidth = rInf.GetWidth(); 314 rInf.SetWidth( sal_uInt16(rInf.GetSize().Width()) ); 315 if ( rInf.GetUpper() ) 316 pUpperFnt->DrawText( rInf ); 317 else 318 { 319 sal_Bool bOldBullet = rInf.GetBullet(); 320 rInf.SetBullet( sal_False ); 321 pLowerFnt->DrawText( rInf ); 322 rInf.SetBullet( bOldBullet ); 323 } 324 325 ASSERT( pUpperFnt, "No upper font, dying soon!"); 326 rInf.Shift( pUpperFnt->GetFont()->GetOrientation() ); 327 rInf.SetWidth( nOrgWidth ); 328 } 329 330 /************************************************************************* 331 * SwDoDrawCapital::DrawSpace() 332 *************************************************************************/ 333 334 void SwDoDrawCapital::DrawSpace( Point &rPos ) 335 { 336 static sal_Char __READONLY_DATA sDoubleSpace[] = " "; 337 338 long nDiff = rInf.GetPos().X() - rPos.X(); 339 340 Point aPos( rPos ); 341 const sal_Bool bSwitchL2R = rInf.GetFrm()->IsRightToLeft() && 342 ! rInf.IsIgnoreFrmRTL(); 343 344 345 if ( bSwitchL2R ) 346 rInf.GetFrm()->SwitchLTRtoRTL( aPos ); 347 348 const sal_uLong nMode = rInf.GetpOut()->GetLayoutMode(); 349 const sal_Bool bBidiPor = ( bSwitchL2R != 350 ( 0 != ( TEXT_LAYOUT_BIDI_RTL & nMode ) ) ); 351 352 if ( bBidiPor ) 353 nDiff = -nDiff; 354 355 if ( rInf.GetFrm()->IsVertical() ) 356 rInf.GetFrm()->SwitchHorizontalToVertical( aPos ); 357 358 if ( nDiff ) 359 { 360 rInf.ApplyAutoColor(); 361 GetOut().DrawStretchText( aPos, nDiff, 362 XubString( sDoubleSpace, RTL_TEXTENCODING_MS_1252 ), 0, 2 ); 363 } 364 rPos.X() = rInf.GetPos().X() + rInf.GetWidth(); 365 } 366 367 /************************************************************************* 368 * SwSubFont::DrawCapital() 369 *************************************************************************/ 370 371 void SwSubFont::DrawCapital( SwDrawTextInfo &rInf ) 372 { 373 // Es wird vorausgesetzt, dass rPos bereits kalkuliert ist! 374 // hochgezogen in SwFont: const Point aPos( CalcPos(rPos) ); 375 rInf.SetDrawSpace( GetUnderline() != UNDERLINE_NONE || 376 GetOverline() != UNDERLINE_NONE || 377 GetStrikeout() != STRIKEOUT_NONE ); 378 SwDoDrawCapital aDo( rInf ); 379 DoOnCapitals( aDo ); 380 } 381 382 /************************************************************************* 383 * class SwDoDrawCapital 384 *************************************************************************/ 385 386 class SwDoCapitalCrsrOfst : public SwDoCapitals 387 { 388 protected: 389 SwFntObj *pUpperFnt; 390 SwFntObj *pLowerFnt; 391 xub_StrLen nCrsr; 392 sal_uInt16 nOfst; 393 public: 394 SwDoCapitalCrsrOfst( SwDrawTextInfo &rInfo, const sal_uInt16 nOfs ) : 395 SwDoCapitals( rInfo ), nCrsr( 0 ), nOfst( nOfs ) 396 { } 397 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); 398 virtual void Do(); 399 400 void DrawSpace( const Point &rPos ); 401 inline xub_StrLen GetCrsr(){ return nCrsr; } 402 }; 403 404 void SwDoCapitalCrsrOfst::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) 405 { 406 pUpperFnt = pUpperFont; 407 pLowerFnt = pLowerFont; 408 } 409 410 void SwDoCapitalCrsrOfst::Do() 411 { 412 if ( nOfst ) 413 { 414 if ( nOfst > rInf.GetSize().Width() ) 415 { 416 nOfst = nOfst - sal_uInt16(rInf.GetSize().Width()); 417 nCrsr = nCrsr + rInf.GetLen(); 418 } 419 else 420 { 421 SwDrawTextInfo aDrawInf( rInf.GetShell(), *rInf.GetpOut(), 422 rInf.GetScriptInfo(), 423 rInf.GetText(), 424 rInf.GetIdx(), 425 rInf.GetLen(), 0, sal_False ); 426 aDrawInf.SetOfst( nOfst ); 427 aDrawInf.SetKern( rInf.GetKern() ); 428 aDrawInf.SetKanaComp( rInf.GetKanaComp() ); 429 aDrawInf.SetFrm( rInf.GetFrm() ); 430 aDrawInf.SetFont( rInf.GetFont() ); 431 432 if ( rInf.GetUpper() ) 433 { 434 aDrawInf.SetSpace( 0 ); 435 nCrsr = nCrsr + pUpperFnt->GetCrsrOfst( aDrawInf ); 436 } 437 else 438 { 439 aDrawInf.SetSpace( rInf.GetSpace() ); 440 nCrsr = nCrsr + pLowerFnt->GetCrsrOfst( aDrawInf ); 441 } 442 nOfst = 0; 443 } 444 } 445 } 446 447 /************************************************************************* 448 * SwSubFont::GetCapitalCrsrOfst() 449 *************************************************************************/ 450 451 xub_StrLen SwSubFont::GetCapitalCrsrOfst( SwDrawTextInfo& rInf ) 452 { 453 const long nOldKern = rInf.GetKern(); 454 rInf.SetKern( CheckKerning() ); 455 SwDoCapitalCrsrOfst aDo( rInf, rInf.GetOfst() ); 456 Point aPos; 457 rInf.SetPos( aPos ); 458 rInf.SetDrawSpace( sal_False ); 459 DoOnCapitals( aDo ); 460 rInf.SetKern( nOldKern ); 461 return aDo.GetCrsr(); 462 } 463 464 /************************************************************************* 465 * class SwDoDrawStretchCapital 466 *************************************************************************/ 467 468 class SwDoDrawStretchCapital : public SwDoDrawCapital 469 { 470 const xub_StrLen nStrLen; 471 const sal_uInt16 nCapWidth; 472 const sal_uInt16 nOrgWidth; 473 public: 474 virtual void Do(); 475 476 SwDoDrawStretchCapital( SwDrawTextInfo &rInfo, const sal_uInt16 nCapitalWidth ) 477 : SwDoDrawCapital( rInfo ), 478 nStrLen( rInfo.GetLen() ), 479 nCapWidth( nCapitalWidth ), 480 nOrgWidth( rInfo.GetWidth() ) 481 { } 482 }; 483 484 /************************************************************************* 485 * SwDoDrawStretchCapital 486 *************************************************************************/ 487 488 void SwDoDrawStretchCapital::Do() 489 { 490 SV_STAT( nDrawStretchText ); 491 sal_uInt16 nPartWidth = sal_uInt16(rInf.GetSize().Width()); 492 493 if( rInf.GetLen() ) 494 { 495 // 4023: Kapitaelchen und Kerning. 496 long nDiff = long(nOrgWidth) - long(nCapWidth); 497 if( nDiff ) 498 { 499 nDiff *= rInf.GetLen(); 500 nDiff /= (long) nStrLen; 501 nDiff += nPartWidth; 502 if( 0 < nDiff ) 503 nPartWidth = sal_uInt16(nDiff); 504 } 505 506 rInf.ApplyAutoColor(); 507 508 Point aPos( rInf.GetPos() ); 509 const sal_Bool bSwitchL2R = rInf.GetFrm()->IsRightToLeft() && 510 ! rInf.IsIgnoreFrmRTL(); 511 512 if ( bSwitchL2R ) 513 rInf.GetFrm()->SwitchLTRtoRTL( aPos ); 514 515 if ( rInf.GetFrm()->IsVertical() ) 516 rInf.GetFrm()->SwitchHorizontalToVertical( aPos ); 517 518 // Optimierung: 519 if( 1 >= rInf.GetLen() ) 520 GetOut().DrawText( aPos, rInf.GetText(), rInf.GetIdx(), 521 rInf.GetLen() ); 522 else 523 GetOut().DrawStretchText( aPos, nPartWidth, 524 rInf.GetText(), rInf.GetIdx(), rInf.GetLen() ); 525 } 526 ((Point&)rInf.GetPos()).X() += nPartWidth; 527 } 528 529 /************************************************************************* 530 * SwSubFont::DrawStretchCapital() 531 *************************************************************************/ 532 533 void SwSubFont::DrawStretchCapital( SwDrawTextInfo &rInf ) 534 { 535 // Es wird vorausgesetzt, dass rPos bereits kalkuliert ist! 536 // hochgezogen in SwFont: const Point aPos( CalcPos(rPos) ); 537 538 if( rInf.GetLen() == STRING_LEN ) 539 rInf.SetLen( rInf.GetText().Len() ); 540 541 const Point& rOldPos = rInf.GetPos(); 542 const sal_uInt16 nCapWidth = (sal_uInt16)( GetCapitalSize( rInf ).Width() ); 543 rInf.SetPos( rOldPos ); 544 545 rInf.SetDrawSpace( GetUnderline() != UNDERLINE_NONE || 546 GetOverline() != UNDERLINE_NONE || 547 GetStrikeout() != STRIKEOUT_NONE ); 548 SwDoDrawStretchCapital aDo( rInf, nCapWidth ); 549 DoOnCapitals( aDo ); 550 } 551 552 /************************************************************************* 553 * SwSubFont::DoOnCapitals() const 554 *************************************************************************/ 555 556 // JP 22.8.2001 - global optimization off - Bug 91245 / 91223 557 #ifdef _MSC_VER 558 #pragma optimize("g",off) 559 #endif 560 561 void SwSubFont::DoOnCapitals( SwDoCapitals &rDo ) 562 { 563 ASSERT( pLastFont, "SwFont::DoOnCapitals: No LastFont?!" ); 564 565 Size aPartSize; 566 long nKana = 0; 567 const XubString aTxt( CalcCaseMap( rDo.GetInf().GetText() ) ); 568 xub_StrLen nMaxPos = Min( sal_uInt16(rDo.GetInf().GetText().Len() 569 - rDo.GetInf().GetIdx()), rDo.GetInf().GetLen() ); 570 rDo.GetInf().SetLen( nMaxPos ); 571 572 const XubString& rOldText = rDo.GetInf().GetText(); 573 rDo.GetInf().SetText( aTxt ); 574 rDo.GetInf().SetSize( aPartSize ); 575 xub_StrLen nPos = rDo.GetInf().GetIdx(); 576 xub_StrLen nOldPos = nPos; 577 nMaxPos = nMaxPos + nPos; 578 579 // #107816# 580 // Look if the length of the original text and the ToUpper-converted 581 // text is different. If yes, do special handling. 582 XubString aNewText; 583 SwCapitalInfo aCapInf( rOldText ); 584 sal_Bool bCaseMapLengthDiffers( aTxt.Len() != rOldText.Len() ); 585 if ( bCaseMapLengthDiffers ) 586 rDo.SetCapInf( aCapInf ); 587 588 SwFntObj *pOldLast = pLastFont; 589 SwFntAccess *pBigFontAccess = NULL; 590 SwFntObj *pBigFont; 591 SwFntAccess *pSpaceFontAccess = NULL; 592 SwFntObj *pSpaceFont = NULL; 593 594 const void *pMagic2 = NULL; 595 sal_uInt16 nIndex2 = 0; 596 SwSubFont aFont( *this ); 597 Point aStartPos( rDo.GetInf().GetPos() ); 598 599 const sal_Bool bTextLines = aFont.GetUnderline() != UNDERLINE_NONE 600 || aFont.GetOverline() != UNDERLINE_NONE 601 || aFont.GetStrikeout() != STRIKEOUT_NONE; 602 const sal_Bool bWordWise = bTextLines && aFont.IsWordLineMode() && 603 rDo.GetInf().GetDrawSpace(); 604 const long nTmpKern = rDo.GetInf().GetKern(); 605 606 if ( bTextLines ) 607 { 608 if ( bWordWise ) 609 { 610 aFont.SetWordLineMode( sal_False ); 611 pSpaceFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, 612 rDo.GetInf().GetShell() ); 613 pSpaceFont = pSpaceFontAccess->Get(); 614 } 615 else 616 pSpaceFont = pLastFont; 617 618 // Wir basteln uns einen Font fuer die Grossbuchstaben: 619 aFont.SetUnderline( UNDERLINE_NONE ); 620 aFont.SetOverline( UNDERLINE_NONE ); 621 aFont.SetStrikeout( STRIKEOUT_NONE ); 622 pMagic2 = NULL; 623 nIndex2 = 0; 624 pBigFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, 625 rDo.GetInf().GetShell() ); 626 pBigFont = pBigFontAccess->Get(); 627 } 628 else 629 pBigFont = pLastFont; 630 631 // Hier entsteht der Kleinbuchstabenfont: 632 aFont.SetProportion( sal_uInt8( (aFont.GetPropr()*KAPITAELCHENPROP) / 100L) ); 633 pMagic2 = NULL; 634 nIndex2 = 0; 635 SwFntAccess *pSmallFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, 636 rDo.GetInf().GetShell() ); 637 SwFntObj *pSmallFont = pSmallFontAccess->Get(); 638 639 rDo.Init( pBigFont, pSmallFont ); 640 OutputDevice* pOutSize = pSmallFont->GetPrt(); 641 if( !pOutSize ) 642 pOutSize = &rDo.GetOut(); 643 OutputDevice* pOldOut = &rDo.GetOut(); 644 645 const LanguageType eLng = LANGUAGE_DONTKNOW == GetLanguage() 646 ? LANGUAGE_SYSTEM : GetLanguage(); 647 648 if( nPos < nMaxPos ) 649 { 650 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfCharBlock( rOldText, nPos, 651 pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); 652 if( nPos == STRING_LEN ) 653 nPos = nOldPos; 654 else if( nPos > nMaxPos ) 655 nPos = nMaxPos; 656 } 657 658 while( nOldPos < nMaxPos ) 659 { 660 661 // The lower ones... 662 if( nOldPos != nPos ) 663 { 664 SV_STAT( nGetTextSize ); 665 pLastFont = pSmallFont; 666 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); 667 668 // #107816#, #i14820# 669 if( bCaseMapLengthDiffers ) 670 { 671 // Build an own 'changed' string for the given part of the 672 // source string and use it. That new string may differ in length 673 // from the source string. 674 const XubString aSnippet( rOldText, nOldPos, nPos - nOldPos); 675 aNewText = CalcCaseMap( aSnippet ); 676 aCapInf.nIdx = nOldPos; 677 aCapInf.nLen = nPos - nOldPos; 678 rDo.GetInf().SetIdx( 0 ); 679 rDo.GetInf().SetLen( aNewText.Len() ); 680 rDo.GetInf().SetText( aNewText ); 681 } 682 else 683 { 684 rDo.GetInf().SetIdx( nOldPos ); 685 rDo.GetInf().SetLen( nPos - nOldPos ); 686 } 687 688 rDo.GetInf().SetUpper( sal_False ); 689 rDo.GetInf().SetOut( *pOutSize ); 690 aPartSize = pSmallFont->GetTextSize( rDo.GetInf() ); 691 nKana += rDo.GetInf().GetKanaDiff(); 692 rDo.GetInf().SetOut( *pOldOut ); 693 if( nTmpKern && nPos < nMaxPos ) 694 aPartSize.Width() += nTmpKern; 695 rDo.Do(); 696 nOldPos = nPos; 697 } 698 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharBlock( rOldText, nPos, 699 pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); 700 if( nPos == STRING_LEN || nPos > nMaxPos ) 701 nPos = nMaxPos; 702 ASSERT( nPos, "nextCharBlock not implemented?" ); 703 #ifdef DBG_UTIL 704 if( !nPos ) 705 nPos = nMaxPos; 706 #endif 707 // The upper ones... 708 if( nOldPos != nPos ) 709 { 710 const long nSpaceAdd = rDo.GetInf().GetSpace() / SPACING_PRECISION_FACTOR; 711 712 do 713 { 714 rDo.GetInf().SetUpper( sal_True ); 715 pLastFont = pBigFont; 716 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); 717 xub_StrLen nTmp; 718 if( bWordWise ) 719 { 720 nTmp = nOldPos; 721 while( nTmp < nPos && CH_BLANK == rOldText.GetChar( nTmp ) ) 722 ++nTmp; 723 if( nOldPos < nTmp ) 724 { 725 pLastFont = pSpaceFont; 726 pLastFont->SetDevFont( rDo.GetInf().GetShell(), 727 rDo.GetOut() ); 728 ((SwDoDrawCapital&)rDo).DrawSpace( aStartPos ); 729 pLastFont = pBigFont; 730 pLastFont->SetDevFont( rDo.GetInf().GetShell(), 731 rDo.GetOut() ); 732 733 // #107816#, #i14820# 734 if( bCaseMapLengthDiffers ) 735 { 736 // Build an own 'changed' string for the given part of the 737 // source string and use it. That new string may differ in length 738 // from the source string. 739 const XubString aSnippet( rOldText, nOldPos, nTmp - nOldPos); 740 aNewText = CalcCaseMap( aSnippet ); 741 aCapInf.nIdx = nOldPos; 742 aCapInf.nLen = nTmp - nOldPos; 743 rDo.GetInf().SetIdx( 0 ); 744 rDo.GetInf().SetLen( aNewText.Len() ); 745 rDo.GetInf().SetText( aNewText ); 746 } 747 else 748 { 749 rDo.GetInf().SetIdx( nOldPos ); 750 rDo.GetInf().SetLen( nTmp - nOldPos ); 751 } 752 753 rDo.GetInf().SetOut( *pOutSize ); 754 aPartSize = pBigFont->GetTextSize( rDo.GetInf() ); 755 nKana += rDo.GetInf().GetKanaDiff(); 756 rDo.GetInf().SetOut( *pOldOut ); 757 if( nSpaceAdd ) 758 aPartSize.Width() += nSpaceAdd * ( nTmp - nOldPos ); 759 if( nTmpKern && nPos < nMaxPos ) 760 aPartSize.Width() += nTmpKern; 761 rDo.Do(); 762 aStartPos = rDo.GetInf().GetPos(); 763 nOldPos = nTmp; 764 } 765 766 while( nTmp < nPos && CH_BLANK != rOldText.GetChar( nTmp ) ) 767 ++nTmp; 768 } 769 else 770 nTmp = nPos; 771 if( nTmp > nOldPos ) 772 { 773 // #107816#, #i14820# 774 if( bCaseMapLengthDiffers ) 775 { 776 // Build an own 'changed' string for the given part of the 777 // source string and use it. That new string may differ in length 778 // from the source string. 779 const XubString aSnippet( rOldText, nOldPos, nTmp - nOldPos); 780 aNewText = CalcCaseMap( aSnippet ); 781 aCapInf.nIdx = nOldPos; 782 aCapInf.nLen = nTmp - nOldPos; 783 rDo.GetInf().SetIdx( 0 ); 784 rDo.GetInf().SetLen( aNewText.Len() ); 785 rDo.GetInf().SetText( aNewText ); 786 } 787 else 788 { 789 rDo.GetInf().SetIdx( nOldPos ); 790 rDo.GetInf().SetLen( nTmp - nOldPos ); 791 } 792 793 rDo.GetInf().SetOut( *pOutSize ); 794 aPartSize = pBigFont->GetTextSize( rDo.GetInf() ); 795 nKana += rDo.GetInf().GetKanaDiff(); 796 rDo.GetInf().SetOut( *pOldOut ); 797 if( !bWordWise && rDo.GetInf().GetSpace() ) 798 { 799 for( xub_StrLen nI = nOldPos; nI < nPos; ++nI ) 800 { 801 if( CH_BLANK == rOldText.GetChar( nI ) ) 802 aPartSize.Width() += nSpaceAdd; 803 } 804 } 805 if( nTmpKern && nPos < nMaxPos ) 806 aPartSize.Width() += nTmpKern; 807 rDo.Do(); 808 nOldPos = nTmp; 809 } 810 } while( nOldPos != nPos ); 811 } 812 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfCharBlock( rOldText, nPos, 813 pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); 814 if( nPos == STRING_LEN || nPos > nMaxPos ) 815 nPos = nMaxPos; 816 ASSERT( nPos, "endOfCharBlock not implemented?" ); 817 #ifdef DBG_UTIL 818 if( !nPos ) 819 nPos = nMaxPos; 820 #endif 821 } 822 823 // Aufraeumen: 824 if( pBigFont != pOldLast ) 825 delete pBigFontAccess; 826 827 if( bTextLines ) 828 { 829 if( rDo.GetInf().GetDrawSpace() ) 830 { 831 pLastFont = pSpaceFont; 832 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); 833 ( (SwDoDrawCapital&) rDo ).DrawSpace( aStartPos ); 834 } 835 if ( bWordWise ) 836 delete pSpaceFontAccess; 837 } 838 pLastFont = pOldLast; 839 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); 840 841 delete pSmallFontAccess; 842 rDo.GetInf().SetText( rOldText ); 843 rDo.GetInf().SetKanaDiff( nKana ); 844 } 845 846 // JP 22.8.2001 - global optimization off - Bug 91245 / 91223 847 #ifdef _MSC_VER 848 #pragma optimize("g",on) 849 #endif 850 851 852