merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / txtnode / fntcap.cxx
blob9f32dd7975c8d6a1ad0fde3a0597142e9fbf0b16
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fntcap.cxx,v $
10 * $Revision: 1.27.210.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <svx/cmapitem.hxx>
38 #ifndef _OUTDEV_HXX //autogen
39 #include <vcl/outdev.hxx>
40 #endif
41 #ifndef _COM_SUN_STAR_I18N_CHARTYPE_HDL
42 #include <com/sun/star/i18n/CharType.hdl>
43 #endif
44 #ifndef _COM_SUN_STAR_I18N_WORDTYPE_HDL
45 #include <com/sun/star/i18n/WordType.hdl>
46 #endif
48 #ifndef _PRINT_HXX //autogen
49 #include <vcl/print.hxx>
50 #endif
51 #include <errhdl.hxx>
52 #include <fntcache.hxx>
53 #include <swfont.hxx>
54 #include <breakit.hxx>
55 #include <txtfrm.hxx> // SwTxtFrm
56 #include <scriptinfo.hxx>
58 using namespace ::com::sun::star::i18n;
61 #define KAPITAELCHENPROP 66
63 /*************************************************************************
64 * class SwCapitalInfo
66 * The information encapsulated in SwCapitalInfo is required
67 * by the ::Do functions. They contain the information about
68 * the original string, whereas rDo.GetInf() contains information
69 * about the display string.
70 *************************************************************************/
72 class SwCapitalInfo
74 public:
75 explicit SwCapitalInfo( const XubString& rOrigText ) :
76 rString( rOrigText ), nIdx( 0 ), nLen( 0 ) {};
77 const XubString& rString;
78 xub_StrLen nIdx;
79 xub_StrLen nLen;
82 /*************************************************************************
83 * xub_StrLen lcl_CalcCaseMap()
85 * rFnt: required for CalcCaseMap
86 * rOrigString: The original string
87 * nOfst: Position of the substring in rOrigString
88 * nLen: Length if the substring in rOrigString
89 * nIdx: Referes to a position in the display string and should be mapped
90 * to a position in rOrigString
91 *************************************************************************/
93 xub_StrLen lcl_CalcCaseMap( const SwFont& rFnt,
94 const XubString& rOrigString,
95 xub_StrLen nOfst,
96 xub_StrLen nLen,
97 xub_StrLen nIdx )
99 int j = 0;
100 const xub_StrLen nEnd = nOfst + nLen;
101 ASSERT( nEnd <= rOrigString.Len(), "lcl_CalcCaseMap: Wrong parameters" )
103 // special case for title case:
104 const bool bTitle = SVX_CASEMAP_TITEL == rFnt.GetCaseMap() &&
105 pBreakIt->GetBreakIter().is();
106 for ( xub_StrLen i = nOfst; i < nEnd; ++i )
108 XubString aTmp( rOrigString, i, 1 );
110 if ( !bTitle ||
111 pBreakIt->GetBreakIter()->isBeginWord(
112 rOrigString, i,
113 pBreakIt->GetLocale( rFnt.GetLanguage() ),
114 WordType::ANYWORD_IGNOREWHITESPACES ) )
115 aTmp = rFnt.GetActualFont().CalcCaseMap( aTmp );
117 j += aTmp.Len();
119 if ( j > nIdx )
120 return i;
123 return nOfst + nLen;
126 /*************************************************************************
127 * class SwDoCapitals
128 *************************************************************************/
130 class SwDoCapitals
132 protected:
133 SwDrawTextInfo &rInf;
134 SwCapitalInfo* pCapInf; // referes to additional information
135 // required by the ::Do function
136 public:
137 SwDoCapitals ( SwDrawTextInfo &rInfo ) : rInf( rInfo ), pCapInf( 0 ) { }
138 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) = 0;
139 virtual void Do() = 0;
140 inline OutputDevice& GetOut() { return rInf.GetOut(); }
141 inline SwDrawTextInfo& GetInf() { return rInf; }
142 inline SwCapitalInfo* GetCapInf() const { return pCapInf; }
143 inline void SetCapInf( SwCapitalInfo& rNew ) { pCapInf = &rNew; }
146 /*************************************************************************
147 * class SwDoGetCapitalSize
148 *************************************************************************/
150 class SwDoGetCapitalSize : public SwDoCapitals
152 protected:
153 Size aTxtSize;
154 public:
155 SwDoGetCapitalSize( SwDrawTextInfo &rInfo ) : SwDoCapitals ( rInfo ) { }
156 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont );
157 virtual void Do();
158 const Size &GetSize() const { return aTxtSize; }
161 void SwDoGetCapitalSize::Init( SwFntObj *, SwFntObj * )
163 aTxtSize.Height() = 0;
164 aTxtSize.Width() = 0;
167 void SwDoGetCapitalSize::Do()
169 aTxtSize.Width() += rInf.GetSize().Width();
170 if( rInf.GetUpper() )
171 aTxtSize.Height() = rInf.GetSize().Height();
174 /*************************************************************************
175 * SwSubFont::GetCapitalSize()
176 *************************************************************************/
178 Size SwSubFont::GetCapitalSize( SwDrawTextInfo& rInf )
180 // Start:
181 const long nOldKern = rInf.GetKern();
182 rInf.SetKern( CheckKerning() );
183 Point aPos;
184 rInf.SetPos( aPos );
185 rInf.SetSpace( 0 );
186 rInf.SetDrawSpace( FALSE );
187 SwDoGetCapitalSize aDo( rInf );
188 DoOnCapitals( aDo );
189 Size aTxtSize( aDo.GetSize() );
191 // End:
192 if( !aTxtSize.Height() )
194 SV_STAT( nGetTextSize );
195 aTxtSize.Height() = short ( rInf.GetpOut()->GetTextHeight() );
197 rInf.SetKern( nOldKern );
198 return aTxtSize;
201 /*************************************************************************
202 * class SwDoGetCapitalBreak
203 *************************************************************************/
205 class SwDoGetCapitalBreak : public SwDoCapitals
207 protected:
208 xub_StrLen *pExtraPos;
209 long nTxtWidth;
210 xub_StrLen nBreak;
211 public:
212 SwDoGetCapitalBreak( SwDrawTextInfo &rInfo, long nWidth, xub_StrLen *pExtra)
213 : SwDoCapitals ( rInfo ), pExtraPos( pExtra ), nTxtWidth( nWidth ),
214 nBreak( STRING_LEN )
216 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont );
217 virtual void Do();
218 xub_StrLen GetBreak() const { return nBreak; }
221 void SwDoGetCapitalBreak::Init( SwFntObj *, SwFntObj * )
225 void SwDoGetCapitalBreak::Do()
227 if ( nTxtWidth )
229 if ( rInf.GetSize().Width() < nTxtWidth )
230 nTxtWidth -= rInf.GetSize().Width();
231 else
233 xub_StrLen nEnd = rInf.GetEnd();
234 if( pExtraPos )
236 nBreak = GetOut().GetTextBreak( rInf.GetText(), nTxtWidth, '-',
237 *pExtraPos, rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() );
238 if( *pExtraPos > nEnd )
239 *pExtraPos = nEnd;
241 else
242 nBreak = GetOut().GetTextBreak( rInf.GetText(), nTxtWidth,
243 rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() );
245 if( nBreak > nEnd )
246 nBreak = nEnd;
248 // nBreak may be relative to the display string. It has to be
249 // calculated relative to the original string:
250 if ( GetCapInf() )
252 if ( GetCapInf()->nLen != rInf.GetLen() )
253 nBreak = lcl_CalcCaseMap( *rInf.GetFont(),
254 GetCapInf()->rString,
255 GetCapInf()->nIdx,
256 GetCapInf()->nLen, nBreak );
257 else
258 nBreak = nBreak + GetCapInf()->nIdx;
261 nTxtWidth = 0;
266 /*************************************************************************
267 * SwFont::GetCapitalBreak()
268 *************************************************************************/
270 xub_StrLen SwFont::GetCapitalBreak( ViewShell* pSh, const OutputDevice* pOut,
271 const SwScriptInfo* pScript, const XubString& rTxt, long nTextWidth,
272 xub_StrLen *pExtra, const xub_StrLen nIdx, const xub_StrLen nLen )
274 // Start:
275 Point aPos( 0, 0 );
276 SwDrawTextInfo aInfo(pSh, *(OutputDevice*)pOut, pScript, rTxt, nIdx, nLen,
277 0, FALSE);
278 aInfo.SetPos( aPos );
279 aInfo.SetSpace( 0 );
280 aInfo.SetWrong( NULL );
281 aInfo.SetGrammarCheck( NULL );
282 aInfo.SetSmartTags( NULL ); // SMARTTAGS
283 aInfo.SetDrawSpace( FALSE );
284 aInfo.SetKern( CheckKerning() );
285 aInfo.SetKanaComp( pScript ? 0 : 100 );
286 aInfo.SetFont( this );
288 SwDoGetCapitalBreak aDo( aInfo, nTextWidth, pExtra );
289 DoOnCapitals( aDo );
290 return aDo.GetBreak();
293 /*************************************************************************
294 * class SwDoDrawCapital
295 *************************************************************************/
297 class SwDoDrawCapital : public SwDoCapitals
299 protected:
300 SwFntObj *pUpperFnt;
301 SwFntObj *pLowerFnt;
302 public:
303 SwDoDrawCapital( SwDrawTextInfo &rInfo ) :
304 SwDoCapitals( rInfo )
306 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont );
307 virtual void Do();
308 void DrawSpace( Point &rPos );
311 void SwDoDrawCapital::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
313 pUpperFnt = pUpperFont;
314 pLowerFnt = pLowerFont;
317 void SwDoDrawCapital::Do()
319 SV_STAT( nDrawText );
320 USHORT nOrgWidth = rInf.GetWidth();
321 rInf.SetWidth( USHORT(rInf.GetSize().Width()) );
322 if ( rInf.GetUpper() )
323 pUpperFnt->DrawText( rInf );
324 else
326 BOOL bOldBullet = rInf.GetBullet();
327 rInf.SetBullet( FALSE );
328 pLowerFnt->DrawText( rInf );
329 rInf.SetBullet( bOldBullet );
332 ASSERT( pUpperFnt, "No upper font, dying soon!");
333 rInf.Shift( pUpperFnt->GetFont()->GetOrientation() );
334 rInf.SetWidth( nOrgWidth );
337 /*************************************************************************
338 * SwDoDrawCapital::DrawSpace()
339 *************************************************************************/
341 void SwDoDrawCapital::DrawSpace( Point &rPos )
343 static sal_Char __READONLY_DATA sDoubleSpace[] = " ";
345 long nDiff = rInf.GetPos().X() - rPos.X();
347 Point aPos( rPos );
348 const BOOL bSwitchL2R = rInf.GetFrm()->IsRightToLeft() &&
349 ! rInf.IsIgnoreFrmRTL();
352 if ( bSwitchL2R )
353 rInf.GetFrm()->SwitchLTRtoRTL( aPos );
355 const ULONG nMode = rInf.GetpOut()->GetLayoutMode();
356 const BOOL bBidiPor = ( bSwitchL2R !=
357 ( 0 != ( TEXT_LAYOUT_BIDI_RTL & nMode ) ) );
359 if ( bBidiPor )
360 nDiff = -nDiff;
362 if ( rInf.GetFrm()->IsVertical() )
363 rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
365 if ( nDiff )
367 rInf.ApplyAutoColor();
368 GetOut().DrawStretchText( aPos, nDiff,
369 XubString( sDoubleSpace, RTL_TEXTENCODING_MS_1252 ), 0, 2 );
371 rPos.X() = rInf.GetPos().X() + rInf.GetWidth();
374 /*************************************************************************
375 * SwSubFont::DrawCapital()
376 *************************************************************************/
378 void SwSubFont::DrawCapital( SwDrawTextInfo &rInf )
380 // Es wird vorausgesetzt, dass rPos bereits kalkuliert ist!
381 // hochgezogen in SwFont: const Point aPos( CalcPos(rPos) );
382 rInf.SetDrawSpace( GetUnderline() != UNDERLINE_NONE ||
383 GetOverline() != UNDERLINE_NONE ||
384 GetStrikeout() != STRIKEOUT_NONE );
385 SwDoDrawCapital aDo( rInf );
386 DoOnCapitals( aDo );
389 /*************************************************************************
390 * class SwDoDrawCapital
391 *************************************************************************/
393 class SwDoCapitalCrsrOfst : public SwDoCapitals
395 protected:
396 SwFntObj *pUpperFnt;
397 SwFntObj *pLowerFnt;
398 xub_StrLen nCrsr;
399 USHORT nOfst;
400 public:
401 SwDoCapitalCrsrOfst( SwDrawTextInfo &rInfo, const USHORT nOfs ) :
402 SwDoCapitals( rInfo ), nCrsr( 0 ), nOfst( nOfs )
404 virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont );
405 virtual void Do();
407 void DrawSpace( const Point &rPos );
408 inline xub_StrLen GetCrsr(){ return nCrsr; }
411 void SwDoCapitalCrsrOfst::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
413 pUpperFnt = pUpperFont;
414 pLowerFnt = pLowerFont;
417 void SwDoCapitalCrsrOfst::Do()
419 if ( nOfst )
421 if ( nOfst > rInf.GetSize().Width() )
423 nOfst = nOfst - USHORT(rInf.GetSize().Width());
424 nCrsr = nCrsr + rInf.GetLen();
426 else
428 SwDrawTextInfo aDrawInf( rInf.GetShell(), *rInf.GetpOut(),
429 rInf.GetScriptInfo(),
430 rInf.GetText(),
431 rInf.GetIdx(),
432 rInf.GetLen(), 0, FALSE );
433 aDrawInf.SetOfst( nOfst );
434 aDrawInf.SetKern( rInf.GetKern() );
435 aDrawInf.SetKanaComp( rInf.GetKanaComp() );
436 aDrawInf.SetFrm( rInf.GetFrm() );
437 aDrawInf.SetFont( rInf.GetFont() );
439 if ( rInf.GetUpper() )
441 aDrawInf.SetSpace( 0 );
442 nCrsr = nCrsr + pUpperFnt->GetCrsrOfst( aDrawInf );
444 else
446 aDrawInf.SetSpace( rInf.GetSpace() );
447 nCrsr = nCrsr + pLowerFnt->GetCrsrOfst( aDrawInf );
449 nOfst = 0;
454 /*************************************************************************
455 * SwSubFont::GetCapitalCrsrOfst()
456 *************************************************************************/
458 xub_StrLen SwSubFont::GetCapitalCrsrOfst( SwDrawTextInfo& rInf )
460 const long nOldKern = rInf.GetKern();
461 rInf.SetKern( CheckKerning() );
462 SwDoCapitalCrsrOfst aDo( rInf, rInf.GetOfst() );
463 Point aPos;
464 rInf.SetPos( aPos );
465 rInf.SetDrawSpace( FALSE );
466 DoOnCapitals( aDo );
467 rInf.SetKern( nOldKern );
468 return aDo.GetCrsr();
471 /*************************************************************************
472 * class SwDoDrawStretchCapital
473 *************************************************************************/
475 class SwDoDrawStretchCapital : public SwDoDrawCapital
477 const xub_StrLen nStrLen;
478 const USHORT nCapWidth;
479 const USHORT nOrgWidth;
480 public:
481 virtual void Do();
483 SwDoDrawStretchCapital( SwDrawTextInfo &rInfo, const USHORT nCapitalWidth )
484 : SwDoDrawCapital( rInfo ),
485 nStrLen( rInfo.GetLen() ),
486 nCapWidth( nCapitalWidth ),
487 nOrgWidth( rInfo.GetWidth() )
491 /*************************************************************************
492 * SwDoDrawStretchCapital
493 *************************************************************************/
495 void SwDoDrawStretchCapital::Do()
497 SV_STAT( nDrawStretchText );
498 USHORT nPartWidth = USHORT(rInf.GetSize().Width());
500 if( rInf.GetLen() )
502 // 4023: Kapitaelchen und Kerning.
503 long nDiff = long(nOrgWidth) - long(nCapWidth);
504 if( nDiff )
506 nDiff *= rInf.GetLen();
507 nDiff /= (long) nStrLen;
508 nDiff += nPartWidth;
509 if( 0 < nDiff )
510 nPartWidth = USHORT(nDiff);
513 rInf.ApplyAutoColor();
515 Point aPos( rInf.GetPos() );
516 const BOOL bSwitchL2R = rInf.GetFrm()->IsRightToLeft() &&
517 ! rInf.IsIgnoreFrmRTL();
519 if ( bSwitchL2R )
520 rInf.GetFrm()->SwitchLTRtoRTL( aPos );
522 if ( rInf.GetFrm()->IsVertical() )
523 rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
525 // Optimierung:
526 if( 1 >= rInf.GetLen() )
527 GetOut().DrawText( aPos, rInf.GetText(), rInf.GetIdx(),
528 rInf.GetLen() );
529 else
530 GetOut().DrawStretchText( aPos, nPartWidth,
531 rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
533 ((Point&)rInf.GetPos()).X() += nPartWidth;
536 /*************************************************************************
537 * SwSubFont::DrawStretchCapital()
538 *************************************************************************/
540 void SwSubFont::DrawStretchCapital( SwDrawTextInfo &rInf )
542 // Es wird vorausgesetzt, dass rPos bereits kalkuliert ist!
543 // hochgezogen in SwFont: const Point aPos( CalcPos(rPos) );
545 if( rInf.GetLen() == STRING_LEN )
546 rInf.SetLen( rInf.GetText().Len() );
548 const Point& rOldPos = rInf.GetPos();
549 const USHORT nCapWidth = (USHORT)( GetCapitalSize( rInf ).Width() );
550 rInf.SetPos( rOldPos );
552 rInf.SetDrawSpace( GetUnderline() != UNDERLINE_NONE ||
553 GetOverline() != UNDERLINE_NONE ||
554 GetStrikeout() != STRIKEOUT_NONE );
555 SwDoDrawStretchCapital aDo( rInf, nCapWidth );
556 DoOnCapitals( aDo );
559 /*************************************************************************
560 * SwSubFont::DoOnCapitals() const
561 *************************************************************************/
563 // JP 22.8.2001 - global optimization off - Bug 91245 / 91223
564 #ifdef _MSC_VER
565 #pragma optimize("g",off)
566 #endif
568 void SwSubFont::DoOnCapitals( SwDoCapitals &rDo )
570 ASSERT( pLastFont, "SwFont::DoOnCapitals: No LastFont?!" );
572 Size aPartSize;
573 long nKana = 0;
574 const XubString aTxt( CalcCaseMap( rDo.GetInf().GetText() ) );
575 xub_StrLen nMaxPos = Min( USHORT(rDo.GetInf().GetText().Len()
576 - rDo.GetInf().GetIdx()), rDo.GetInf().GetLen() );
577 rDo.GetInf().SetLen( nMaxPos );
579 const XubString& rOldText = rDo.GetInf().GetText();
580 rDo.GetInf().SetText( aTxt );
581 rDo.GetInf().SetSize( aPartSize );
582 xub_StrLen nPos = rDo.GetInf().GetIdx();
583 xub_StrLen nOldPos = nPos;
584 nMaxPos = nMaxPos + nPos;
586 // #107816#
587 // Look if the length of the original text and the ToUpper-converted
588 // text is different. If yes, do special handling.
589 XubString aNewText;
590 SwCapitalInfo aCapInf( rOldText );
591 sal_Bool bCaseMapLengthDiffers( aTxt.Len() != rOldText.Len() );
592 if ( bCaseMapLengthDiffers )
593 rDo.SetCapInf( aCapInf );
595 SwFntObj *pOldLast = pLastFont;
596 SwFntAccess *pBigFontAccess = NULL;
597 SwFntObj *pBigFont;
598 SwFntAccess *pSpaceFontAccess = NULL;
599 SwFntObj *pSpaceFont = NULL;
601 const void *pMagic2 = NULL;
602 USHORT nIndex2 = 0;
603 SwSubFont aFont( *this );
604 Point aStartPos( rDo.GetInf().GetPos() );
606 const BOOL bTextLines = aFont.GetUnderline() != UNDERLINE_NONE
607 || aFont.GetOverline() != UNDERLINE_NONE
608 || aFont.GetStrikeout() != STRIKEOUT_NONE;
609 const BOOL bWordWise = bTextLines && aFont.IsWordLineMode() &&
610 rDo.GetInf().GetDrawSpace();
611 const long nTmpKern = rDo.GetInf().GetKern();
613 if ( bTextLines )
615 if ( bWordWise )
617 aFont.SetWordLineMode( FALSE );
618 pSpaceFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont,
619 rDo.GetInf().GetShell() );
620 pSpaceFont = pSpaceFontAccess->Get();
622 else
623 pSpaceFont = pLastFont;
625 // Wir basteln uns einen Font fuer die Grossbuchstaben:
626 aFont.SetUnderline( UNDERLINE_NONE );
627 aFont.SetOverline( UNDERLINE_NONE );
628 aFont.SetStrikeout( STRIKEOUT_NONE );
629 pMagic2 = NULL;
630 nIndex2 = 0;
631 pBigFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont,
632 rDo.GetInf().GetShell() );
633 pBigFont = pBigFontAccess->Get();
635 else
636 pBigFont = pLastFont;
638 // Hier entsteht der Kleinbuchstabenfont:
639 aFont.SetProportion( BYTE( (aFont.GetPropr()*KAPITAELCHENPROP) / 100L) );
640 pMagic2 = NULL;
641 nIndex2 = 0;
642 SwFntAccess *pSmallFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont,
643 rDo.GetInf().GetShell() );
644 SwFntObj *pSmallFont = pSmallFontAccess->Get();
646 rDo.Init( pBigFont, pSmallFont );
647 OutputDevice* pOutSize = pSmallFont->GetPrt();
648 if( !pOutSize )
649 pOutSize = &rDo.GetOut();
650 OutputDevice* pOldOut = &rDo.GetOut();
652 const LanguageType eLng = LANGUAGE_DONTKNOW == GetLanguage()
653 ? LANGUAGE_SYSTEM : GetLanguage();
655 if( nPos < nMaxPos )
657 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfCharBlock( rOldText, nPos,
658 pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER);
659 if( nPos == STRING_LEN )
660 nPos = nOldPos;
661 else if( nPos > nMaxPos )
662 nPos = nMaxPos;
665 while( nOldPos < nMaxPos )
668 // The lower ones...
669 if( nOldPos != nPos )
671 SV_STAT( nGetTextSize );
672 pLastFont = pSmallFont;
673 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
675 // #107816#, #i14820#
676 if( bCaseMapLengthDiffers )
678 // Build an own 'changed' string for the given part of the
679 // source string and use it. That new string may differ in length
680 // from the source string.
681 const XubString aSnippet( rOldText, nOldPos, nPos - nOldPos);
682 aNewText = CalcCaseMap( aSnippet );
683 aCapInf.nIdx = nOldPos;
684 aCapInf.nLen = nPos - nOldPos;
685 rDo.GetInf().SetIdx( 0 );
686 rDo.GetInf().SetLen( aNewText.Len() );
687 rDo.GetInf().SetText( aNewText );
689 else
691 rDo.GetInf().SetIdx( nOldPos );
692 rDo.GetInf().SetLen( nPos - nOldPos );
695 rDo.GetInf().SetUpper( FALSE );
696 rDo.GetInf().SetOut( *pOutSize );
697 aPartSize = pSmallFont->GetTextSize( rDo.GetInf() );
698 nKana += rDo.GetInf().GetKanaDiff();
699 rDo.GetInf().SetOut( *pOldOut );
700 if( nTmpKern && nPos < nMaxPos )
701 aPartSize.Width() += nTmpKern;
702 rDo.Do();
703 nOldPos = nPos;
705 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharBlock( rOldText, nPos,
706 pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER);
707 if( nPos == STRING_LEN || nPos > nMaxPos )
708 nPos = nMaxPos;
709 ASSERT( nPos, "nextCharBlock not implemented?" );
710 #ifndef PRODUCT
711 if( !nPos )
712 nPos = nMaxPos;
713 #endif
714 // The upper ones...
715 if( nOldPos != nPos )
717 const long nSpaceAdd = rDo.GetInf().GetSpace() / SPACING_PRECISION_FACTOR;
721 rDo.GetInf().SetUpper( TRUE );
722 pLastFont = pBigFont;
723 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
724 xub_StrLen nTmp;
725 if( bWordWise )
727 nTmp = nOldPos;
728 while( nTmp < nPos && CH_BLANK == rOldText.GetChar( nTmp ) )
729 ++nTmp;
730 if( nOldPos < nTmp )
732 pLastFont = pSpaceFont;
733 pLastFont->SetDevFont( rDo.GetInf().GetShell(),
734 rDo.GetOut() );
735 ((SwDoDrawCapital&)rDo).DrawSpace( aStartPos );
736 pLastFont = pBigFont;
737 pLastFont->SetDevFont( rDo.GetInf().GetShell(),
738 rDo.GetOut() );
740 // #107816#, #i14820#
741 if( bCaseMapLengthDiffers )
743 // Build an own 'changed' string for the given part of the
744 // source string and use it. That new string may differ in length
745 // from the source string.
746 const XubString aSnippet( rOldText, nOldPos, nTmp - nOldPos);
747 aNewText = CalcCaseMap( aSnippet );
748 aCapInf.nIdx = nOldPos;
749 aCapInf.nLen = nTmp - nOldPos;
750 rDo.GetInf().SetIdx( 0 );
751 rDo.GetInf().SetLen( aNewText.Len() );
752 rDo.GetInf().SetText( aNewText );
754 else
756 rDo.GetInf().SetIdx( nOldPos );
757 rDo.GetInf().SetLen( nTmp - nOldPos );
760 rDo.GetInf().SetOut( *pOutSize );
761 aPartSize = pBigFont->GetTextSize( rDo.GetInf() );
762 nKana += rDo.GetInf().GetKanaDiff();
763 rDo.GetInf().SetOut( *pOldOut );
764 if( nSpaceAdd )
765 aPartSize.Width() += nSpaceAdd * ( nTmp - nOldPos );
766 if( nTmpKern && nPos < nMaxPos )
767 aPartSize.Width() += nTmpKern;
768 rDo.Do();
769 aStartPos = rDo.GetInf().GetPos();
770 nOldPos = nTmp;
773 while( nTmp < nPos && CH_BLANK != rOldText.GetChar( nTmp ) )
774 ++nTmp;
776 else
777 nTmp = nPos;
778 if( nTmp > nOldPos )
780 // #107816#, #i14820#
781 if( bCaseMapLengthDiffers )
783 // Build an own 'changed' string for the given part of the
784 // source string and use it. That new string may differ in length
785 // from the source string.
786 const XubString aSnippet( rOldText, nOldPos, nTmp - nOldPos);
787 aNewText = CalcCaseMap( aSnippet );
788 aCapInf.nIdx = nOldPos;
789 aCapInf.nLen = nTmp - nOldPos;
790 rDo.GetInf().SetIdx( 0 );
791 rDo.GetInf().SetLen( aNewText.Len() );
792 rDo.GetInf().SetText( aNewText );
794 else
796 rDo.GetInf().SetIdx( nOldPos );
797 rDo.GetInf().SetLen( nTmp - nOldPos );
800 rDo.GetInf().SetOut( *pOutSize );
801 aPartSize = pBigFont->GetTextSize( rDo.GetInf() );
802 nKana += rDo.GetInf().GetKanaDiff();
803 rDo.GetInf().SetOut( *pOldOut );
804 if( !bWordWise && rDo.GetInf().GetSpace() )
806 for( xub_StrLen nI = nOldPos; nI < nPos; ++nI )
808 if( CH_BLANK == rOldText.GetChar( nI ) )
809 aPartSize.Width() += nSpaceAdd;
812 if( nTmpKern && nPos < nMaxPos )
813 aPartSize.Width() += nTmpKern;
814 rDo.Do();
815 nOldPos = nTmp;
817 } while( nOldPos != nPos );
819 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfCharBlock( rOldText, nPos,
820 pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER);
821 if( nPos == STRING_LEN || nPos > nMaxPos )
822 nPos = nMaxPos;
823 ASSERT( nPos, "endOfCharBlock not implemented?" );
824 #ifndef PRODUCT
825 if( !nPos )
826 nPos = nMaxPos;
827 #endif
830 // Aufraeumen:
831 if( pBigFont != pOldLast )
832 delete pBigFontAccess;
834 if( bTextLines )
836 if( rDo.GetInf().GetDrawSpace() )
838 pLastFont = pSpaceFont;
839 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
840 ( (SwDoDrawCapital&) rDo ).DrawSpace( aStartPos );
842 if ( bWordWise )
843 delete pSpaceFontAccess;
845 pLastFont = pOldLast;
846 pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
848 delete pSmallFontAccess;
849 rDo.GetInf().SetText( rOldText );
850 rDo.GetInf().SetKanaDiff( nKana );
853 // JP 22.8.2001 - global optimization off - Bug 91245 / 91223
854 #ifdef _MSC_VER
855 #pragma optimize("g",on)
856 #endif