diff options
Diffstat (limited to 'sw/source/core/txtnode/fntcap.cxx')
-rw-r--r-- | sw/source/core/txtnode/fntcap.cxx | 846 |
1 files changed, 846 insertions, 0 deletions
diff --git a/sw/source/core/txtnode/fntcap.cxx b/sw/source/core/txtnode/fntcap.cxx new file mode 100644 index 000000000000..5696984a7dce --- /dev/null +++ b/sw/source/core/txtnode/fntcap.cxx @@ -0,0 +1,846 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + + +#include <hintids.hxx> +#include <editeng/cmapitem.hxx> +#include <editeng/svxfont.hxx> + +#include <vcl/outdev.hxx> +#include <com/sun/star/i18n/CharType.hdl> +#include <com/sun/star/i18n/WordType.hdl> + +#include <vcl/print.hxx> +#include <fntcache.hxx> +#include <swfont.hxx> +#include <breakit.hxx> +#include <txtfrm.hxx> // SwTxtFrm +#include <scriptinfo.hxx> + +using namespace ::com::sun::star::i18n; + +/************************************************************************* + * class SwCapitalInfo + * + * The information encapsulated in SwCapitalInfo is required + * by the ::Do functions. They contain the information about + * the original string, whereas rDo.GetInf() contains information + * about the display string. + *************************************************************************/ + +class SwCapitalInfo +{ +public: + explicit SwCapitalInfo( const XubString& rOrigText ) : + rString( rOrigText ), nIdx( 0 ), nLen( 0 ) {}; + const XubString& rString; + xub_StrLen nIdx; + xub_StrLen nLen; +}; + +/************************************************************************* + * xub_StrLen lcl_CalcCaseMap() + * + * rFnt: required for CalcCaseMap + * rOrigString: The original string + * nOfst: Position of the substring in rOrigString + * nLen: Length if the substring in rOrigString + * nIdx: Referes to a position in the display string and should be mapped + * to a position in rOrigString + *************************************************************************/ + +xub_StrLen lcl_CalcCaseMap( const SwFont& rFnt, + const XubString& rOrigString, + xub_StrLen nOfst, + xub_StrLen nLen, + xub_StrLen nIdx ) +{ + int j = 0; + const xub_StrLen nEnd = nOfst + nLen; + OSL_ENSURE( nEnd <= rOrigString.Len(), "lcl_CalcCaseMap: Wrong parameters" ); + + // special case for title case: + const bool bTitle = SVX_CASEMAP_TITEL == rFnt.GetCaseMap() && + pBreakIt->GetBreakIter().is(); + for ( xub_StrLen i = nOfst; i < nEnd; ++i ) + { + XubString aTmp( rOrigString, i, 1 ); + + if ( !bTitle || + pBreakIt->GetBreakIter()->isBeginWord( + rOrigString, i, + pBreakIt->GetLocale( rFnt.GetLanguage() ), + WordType::ANYWORD_IGNOREWHITESPACES ) ) + aTmp = rFnt.GetActualFont().CalcCaseMap( aTmp ); + + j += aTmp.Len(); + + if ( j > nIdx ) + return i; + } + + return nOfst + nLen; +} + +/************************************************************************* + * class SwDoCapitals + *************************************************************************/ + +class SwDoCapitals +{ +protected: + SwDrawTextInfo &rInf; + SwCapitalInfo* pCapInf; // referes to additional information + // required by the ::Do function +public: + SwDoCapitals ( SwDrawTextInfo &rInfo ) : rInf( rInfo ), pCapInf( 0 ) { } + virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) = 0; + virtual void Do() = 0; + inline OutputDevice& GetOut() { return rInf.GetOut(); } + inline SwDrawTextInfo& GetInf() { return rInf; } + inline SwCapitalInfo* GetCapInf() const { return pCapInf; } + inline void SetCapInf( SwCapitalInfo& rNew ) { pCapInf = &rNew; } +}; + +/************************************************************************* + * class SwDoGetCapitalSize + *************************************************************************/ + +class SwDoGetCapitalSize : public SwDoCapitals +{ +protected: + Size aTxtSize; +public: + SwDoGetCapitalSize( SwDrawTextInfo &rInfo ) : SwDoCapitals ( rInfo ) { } + virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); + virtual void Do(); + const Size &GetSize() const { return aTxtSize; } +}; + +void SwDoGetCapitalSize::Init( SwFntObj *, SwFntObj * ) +{ + aTxtSize.Height() = 0; + aTxtSize.Width() = 0; +} + +void SwDoGetCapitalSize::Do() +{ + aTxtSize.Width() += rInf.GetSize().Width(); + if( rInf.GetUpper() ) + aTxtSize.Height() = rInf.GetSize().Height(); +} + +/************************************************************************* + * SwSubFont::GetCapitalSize() + *************************************************************************/ + +Size SwSubFont::GetCapitalSize( SwDrawTextInfo& rInf ) +{ + // Start: + const long nOldKern = rInf.GetKern(); + rInf.SetKern( CheckKerning() ); + Point aPos; + rInf.SetPos( aPos ); + rInf.SetSpace( 0 ); + rInf.SetDrawSpace( sal_False ); + SwDoGetCapitalSize aDo( rInf ); + DoOnCapitals( aDo ); + Size aTxtSize( aDo.GetSize() ); + + // End: + if( !aTxtSize.Height() ) + { + SV_STAT( nGetTextSize ); + aTxtSize.Height() = short ( rInf.GetpOut()->GetTextHeight() ); + } + rInf.SetKern( nOldKern ); + return aTxtSize; +} + +/************************************************************************* + * class SwDoGetCapitalBreak + *************************************************************************/ + +class SwDoGetCapitalBreak : public SwDoCapitals +{ +protected: + xub_StrLen *pExtraPos; + long nTxtWidth; + xub_StrLen nBreak; +public: + SwDoGetCapitalBreak( SwDrawTextInfo &rInfo, long nWidth, xub_StrLen *pExtra) + : SwDoCapitals ( rInfo ), pExtraPos( pExtra ), nTxtWidth( nWidth ), + nBreak( STRING_LEN ) + { } + virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); + virtual void Do(); + xub_StrLen GetBreak() const { return nBreak; } +}; + +void SwDoGetCapitalBreak::Init( SwFntObj *, SwFntObj * ) +{ +} + +void SwDoGetCapitalBreak::Do() +{ + if ( nTxtWidth ) + { + if ( rInf.GetSize().Width() < nTxtWidth ) + nTxtWidth -= rInf.GetSize().Width(); + else + { + xub_StrLen nEnd = rInf.GetEnd(); + if( pExtraPos ) + { + nBreak = GetOut().GetTextBreak( rInf.GetText(), nTxtWidth, '-', + *pExtraPos, rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() ); + if( *pExtraPos > nEnd ) + *pExtraPos = nEnd; + } + else + nBreak = GetOut().GetTextBreak( rInf.GetText(), nTxtWidth, + rInf.GetIdx(), rInf.GetLen(), rInf.GetKern() ); + + if( nBreak > nEnd ) + nBreak = nEnd; + + // nBreak may be relative to the display string. It has to be + // calculated relative to the original string: + if ( GetCapInf() ) + { + if ( GetCapInf()->nLen != rInf.GetLen() ) + nBreak = lcl_CalcCaseMap( *rInf.GetFont(), + GetCapInf()->rString, + GetCapInf()->nIdx, + GetCapInf()->nLen, nBreak ); + else + nBreak = nBreak + GetCapInf()->nIdx; + } + + nTxtWidth = 0; + } + } +} + +/************************************************************************* + * SwFont::GetCapitalBreak() + *************************************************************************/ + +xub_StrLen SwFont::GetCapitalBreak( ViewShell* pSh, const OutputDevice* pOut, + const SwScriptInfo* pScript, const XubString& rTxt, long nTextWidth, + xub_StrLen *pExtra, const xub_StrLen nIdx, const xub_StrLen nLen ) +{ + // Start: + Point aPos( 0, 0 ); + SwDrawTextInfo aInfo(pSh, *(OutputDevice*)pOut, pScript, rTxt, nIdx, nLen, + 0, sal_False); + aInfo.SetPos( aPos ); + aInfo.SetSpace( 0 ); + aInfo.SetWrong( NULL ); + aInfo.SetGrammarCheck( NULL ); + aInfo.SetSmartTags( NULL ); // SMARTTAGS + aInfo.SetDrawSpace( sal_False ); + aInfo.SetKern( CheckKerning() ); + aInfo.SetKanaComp( pScript ? 0 : 100 ); + aInfo.SetFont( this ); + + SwDoGetCapitalBreak aDo( aInfo, nTextWidth, pExtra ); + DoOnCapitals( aDo ); + return aDo.GetBreak(); +} + +/************************************************************************* + * class SwDoDrawCapital + *************************************************************************/ + +class SwDoDrawCapital : public SwDoCapitals +{ +protected: + SwFntObj *pUpperFnt; + SwFntObj *pLowerFnt; +public: + SwDoDrawCapital( SwDrawTextInfo &rInfo ) : + SwDoCapitals( rInfo ), pUpperFnt(0), pLowerFnt(0) + { } + virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); + virtual void Do(); + void DrawSpace( Point &rPos ); +}; + +void SwDoDrawCapital::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) +{ + pUpperFnt = pUpperFont; + pLowerFnt = pLowerFont; +} + +void SwDoDrawCapital::Do() +{ + SV_STAT( nDrawText ); + sal_uInt16 nOrgWidth = rInf.GetWidth(); + rInf.SetWidth( sal_uInt16(rInf.GetSize().Width()) ); + if ( rInf.GetUpper() ) + pUpperFnt->DrawText( rInf ); + else + { + sal_Bool bOldBullet = rInf.GetBullet(); + rInf.SetBullet( sal_False ); + pLowerFnt->DrawText( rInf ); + rInf.SetBullet( bOldBullet ); + } + + OSL_ENSURE( pUpperFnt, "No upper font, dying soon!"); + rInf.Shift( pUpperFnt->GetFont()->GetOrientation() ); + rInf.SetWidth( nOrgWidth ); +} + +/************************************************************************* + * SwDoDrawCapital::DrawSpace() + *************************************************************************/ + +void SwDoDrawCapital::DrawSpace( Point &rPos ) +{ + static sal_Char const sDoubleSpace[] = " "; + + long nDiff = rInf.GetPos().X() - rPos.X(); + + Point aPos( rPos ); + const sal_Bool bSwitchL2R = rInf.GetFrm()->IsRightToLeft() && + ! rInf.IsIgnoreFrmRTL(); + + + if ( bSwitchL2R ) + rInf.GetFrm()->SwitchLTRtoRTL( aPos ); + + const sal_uLong nMode = rInf.GetpOut()->GetLayoutMode(); + const sal_Bool bBidiPor = ( bSwitchL2R != + ( 0 != ( TEXT_LAYOUT_BIDI_RTL & nMode ) ) ); + + if ( bBidiPor ) + nDiff = -nDiff; + + if ( rInf.GetFrm()->IsVertical() ) + rInf.GetFrm()->SwitchHorizontalToVertical( aPos ); + + if ( nDiff ) + { + rInf.ApplyAutoColor(); + GetOut().DrawStretchText( aPos, nDiff, + XubString( sDoubleSpace, RTL_TEXTENCODING_MS_1252 ), 0, 2 ); + } + rPos.X() = rInf.GetPos().X() + rInf.GetWidth(); +} + +/************************************************************************* + * SwSubFont::DrawCapital() + *************************************************************************/ + +void SwSubFont::DrawCapital( SwDrawTextInfo &rInf ) +{ + // Es wird vorausgesetzt, dass rPos bereits kalkuliert ist! + // hochgezogen in SwFont: const Point aPos( CalcPos(rPos) ); + rInf.SetDrawSpace( GetUnderline() != UNDERLINE_NONE || + GetOverline() != UNDERLINE_NONE || + GetStrikeout() != STRIKEOUT_NONE ); + SwDoDrawCapital aDo( rInf ); + DoOnCapitals( aDo ); +} + +/************************************************************************* + * class SwDoDrawCapital + *************************************************************************/ + +class SwDoCapitalCrsrOfst : public SwDoCapitals +{ +protected: + SwFntObj *pUpperFnt; + SwFntObj *pLowerFnt; + xub_StrLen nCrsr; + sal_uInt16 nOfst; +public: + SwDoCapitalCrsrOfst( SwDrawTextInfo &rInfo, const sal_uInt16 nOfs ) : + SwDoCapitals( rInfo ), pUpperFnt(0), pLowerFnt(0), nCrsr( 0 ), nOfst( nOfs ) + { } + virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ); + virtual void Do(); + + void DrawSpace( const Point &rPos ); + inline xub_StrLen GetCrsr(){ return nCrsr; } +}; + +void SwDoCapitalCrsrOfst::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) +{ + pUpperFnt = pUpperFont; + pLowerFnt = pLowerFont; +} + +void SwDoCapitalCrsrOfst::Do() +{ + if ( nOfst ) + { + if ( nOfst > rInf.GetSize().Width() ) + { + nOfst = nOfst - sal_uInt16(rInf.GetSize().Width()); + nCrsr = nCrsr + rInf.GetLen(); + } + else + { + SwDrawTextInfo aDrawInf( rInf.GetShell(), *rInf.GetpOut(), + rInf.GetScriptInfo(), + rInf.GetText(), + rInf.GetIdx(), + rInf.GetLen(), 0, sal_False ); + aDrawInf.SetOfst( nOfst ); + aDrawInf.SetKern( rInf.GetKern() ); + aDrawInf.SetKanaComp( rInf.GetKanaComp() ); + aDrawInf.SetFrm( rInf.GetFrm() ); + aDrawInf.SetFont( rInf.GetFont() ); + + if ( rInf.GetUpper() ) + { + aDrawInf.SetSpace( 0 ); + nCrsr = nCrsr + pUpperFnt->GetCrsrOfst( aDrawInf ); + } + else + { + aDrawInf.SetSpace( rInf.GetSpace() ); + nCrsr = nCrsr + pLowerFnt->GetCrsrOfst( aDrawInf ); + } + nOfst = 0; + } + } +} + +/************************************************************************* + * SwSubFont::GetCapitalCrsrOfst() + *************************************************************************/ + +xub_StrLen SwSubFont::GetCapitalCrsrOfst( SwDrawTextInfo& rInf ) +{ + const long nOldKern = rInf.GetKern(); + rInf.SetKern( CheckKerning() ); + SwDoCapitalCrsrOfst aDo( rInf, rInf.GetOfst() ); + Point aPos; + rInf.SetPos( aPos ); + rInf.SetDrawSpace( sal_False ); + DoOnCapitals( aDo ); + rInf.SetKern( nOldKern ); + return aDo.GetCrsr(); +} + +/************************************************************************* + * class SwDoDrawStretchCapital + *************************************************************************/ + +class SwDoDrawStretchCapital : public SwDoDrawCapital +{ + const xub_StrLen nStrLen; + const sal_uInt16 nCapWidth; + const sal_uInt16 nOrgWidth; +public: + virtual void Do(); + + SwDoDrawStretchCapital( SwDrawTextInfo &rInfo, const sal_uInt16 nCapitalWidth ) + : SwDoDrawCapital( rInfo ), + nStrLen( rInfo.GetLen() ), + nCapWidth( nCapitalWidth ), + nOrgWidth( rInfo.GetWidth() ) + { } +}; + +/************************************************************************* + * SwDoDrawStretchCapital + *************************************************************************/ + +void SwDoDrawStretchCapital::Do() +{ + SV_STAT( nDrawStretchText ); + sal_uInt16 nPartWidth = sal_uInt16(rInf.GetSize().Width()); + + if( rInf.GetLen() ) + { + // 4023: Kapitaelchen und Kerning. + long nDiff = long(nOrgWidth) - long(nCapWidth); + if( nDiff ) + { + nDiff *= rInf.GetLen(); + nDiff /= (long) nStrLen; + nDiff += nPartWidth; + if( 0 < nDiff ) + nPartWidth = sal_uInt16(nDiff); + } + + rInf.ApplyAutoColor(); + + Point aPos( rInf.GetPos() ); + const sal_Bool bSwitchL2R = rInf.GetFrm()->IsRightToLeft() && + ! rInf.IsIgnoreFrmRTL(); + + if ( bSwitchL2R ) + rInf.GetFrm()->SwitchLTRtoRTL( aPos ); + + if ( rInf.GetFrm()->IsVertical() ) + rInf.GetFrm()->SwitchHorizontalToVertical( aPos ); + + // Optimierung: + if( 1 >= rInf.GetLen() ) + GetOut().DrawText( aPos, rInf.GetText(), rInf.GetIdx(), + rInf.GetLen() ); + else + GetOut().DrawStretchText( aPos, nPartWidth, + rInf.GetText(), rInf.GetIdx(), rInf.GetLen() ); + } + ((Point&)rInf.GetPos()).X() += nPartWidth; +} + +/************************************************************************* + * SwSubFont::DrawStretchCapital() + *************************************************************************/ + +void SwSubFont::DrawStretchCapital( SwDrawTextInfo &rInf ) +{ + // Es wird vorausgesetzt, dass rPos bereits kalkuliert ist! + // hochgezogen in SwFont: const Point aPos( CalcPos(rPos) ); + + if( rInf.GetLen() == STRING_LEN ) + rInf.SetLen( rInf.GetText().Len() ); + + const Point& rOldPos = rInf.GetPos(); + const sal_uInt16 nCapWidth = (sal_uInt16)( GetCapitalSize( rInf ).Width() ); + rInf.SetPos( rOldPos ); + + rInf.SetDrawSpace( GetUnderline() != UNDERLINE_NONE || + GetOverline() != UNDERLINE_NONE || + GetStrikeout() != STRIKEOUT_NONE ); + SwDoDrawStretchCapital aDo( rInf, nCapWidth ); + DoOnCapitals( aDo ); +} + +/************************************************************************* + * SwSubFont::DoOnCapitals() const + *************************************************************************/ + +// JP 22.8.2001 - global optimization off - Bug 91245 / 91223 +#ifdef _MSC_VER +#pragma optimize("g",off) +#endif + +void SwSubFont::DoOnCapitals( SwDoCapitals &rDo ) +{ + OSL_ENSURE( pLastFont, "SwFont::DoOnCapitals: No LastFont?!" ); + + Size aPartSize; + long nKana = 0; + const XubString aTxt( CalcCaseMap( rDo.GetInf().GetText() ) ); + xub_StrLen nMaxPos = Min( sal_uInt16(rDo.GetInf().GetText().Len() + - rDo.GetInf().GetIdx()), rDo.GetInf().GetLen() ); + rDo.GetInf().SetLen( nMaxPos ); + + const XubString& rOldText = rDo.GetInf().GetText(); + rDo.GetInf().SetText( aTxt ); + rDo.GetInf().SetSize( aPartSize ); + xub_StrLen nPos = rDo.GetInf().GetIdx(); + xub_StrLen nOldPos = nPos; + nMaxPos = nMaxPos + nPos; + + // #107816# + // Look if the length of the original text and the ToUpper-converted + // text is different. If yes, do special handling. + XubString aNewText; + SwCapitalInfo aCapInf( rOldText ); + sal_Bool bCaseMapLengthDiffers( aTxt.Len() != rOldText.Len() ); + if ( bCaseMapLengthDiffers ) + rDo.SetCapInf( aCapInf ); + + SwFntObj *pOldLast = pLastFont; + SwFntAccess *pBigFontAccess = NULL; + SwFntObj *pBigFont; + SwFntAccess *pSpaceFontAccess = NULL; + SwFntObj *pSpaceFont = NULL; + + const void *pMagic2 = NULL; + sal_uInt16 nIndex2 = 0; + SwSubFont aFont( *this ); + Point aStartPos( rDo.GetInf().GetPos() ); + + const sal_Bool bTextLines = aFont.GetUnderline() != UNDERLINE_NONE + || aFont.GetOverline() != UNDERLINE_NONE + || aFont.GetStrikeout() != STRIKEOUT_NONE; + const sal_Bool bWordWise = bTextLines && aFont.IsWordLineMode() && + rDo.GetInf().GetDrawSpace(); + const long nTmpKern = rDo.GetInf().GetKern(); + + if ( bTextLines ) + { + if ( bWordWise ) + { + aFont.SetWordLineMode( sal_False ); + pSpaceFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, + rDo.GetInf().GetShell() ); + pSpaceFont = pSpaceFontAccess->Get(); + } + else + pSpaceFont = pLastFont; + + // Wir basteln uns einen Font fuer die Grossbuchstaben: + aFont.SetUnderline( UNDERLINE_NONE ); + aFont.SetOverline( UNDERLINE_NONE ); + aFont.SetStrikeout( STRIKEOUT_NONE ); + pMagic2 = NULL; + nIndex2 = 0; + pBigFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, + rDo.GetInf().GetShell() ); + pBigFont = pBigFontAccess->Get(); + } + else + pBigFont = pLastFont; + + // Hier entsteht der Kleinbuchstabenfont: + aFont.SetProportion( (aFont.GetPropr() * SMALL_CAPS_PERCENTAGE ) / 100L ); + pMagic2 = NULL; + nIndex2 = 0; + SwFntAccess *pSmallFontAccess = new SwFntAccess( pMagic2, nIndex2, &aFont, + rDo.GetInf().GetShell() ); + SwFntObj *pSmallFont = pSmallFontAccess->Get(); + + rDo.Init( pBigFont, pSmallFont ); + OutputDevice* pOutSize = pSmallFont->GetPrt(); + if( !pOutSize ) + pOutSize = &rDo.GetOut(); + OutputDevice* pOldOut = &rDo.GetOut(); + + const LanguageType eLng = LANGUAGE_DONTKNOW == GetLanguage() + ? LANGUAGE_SYSTEM : GetLanguage(); + + if( nPos < nMaxPos ) + { + nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfCharBlock( rOldText, nPos, + pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); + if( nPos == STRING_LEN ) + nPos = nOldPos; + else if( nPos > nMaxPos ) + nPos = nMaxPos; + } + + while( nOldPos < nMaxPos ) + { + + // The lower ones... + if( nOldPos != nPos ) + { + SV_STAT( nGetTextSize ); + pLastFont = pSmallFont; + pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); + + // #107816#, #i14820# + if( bCaseMapLengthDiffers ) + { + // Build an own 'changed' string for the given part of the + // source string and use it. That new string may differ in length + // from the source string. + const XubString aSnippet( rOldText, nOldPos, nPos - nOldPos); + aNewText = CalcCaseMap( aSnippet ); + aCapInf.nIdx = nOldPos; + aCapInf.nLen = nPos - nOldPos; + rDo.GetInf().SetIdx( 0 ); + rDo.GetInf().SetLen( aNewText.Len() ); + rDo.GetInf().SetText( aNewText ); + } + else + { + rDo.GetInf().SetIdx( nOldPos ); + rDo.GetInf().SetLen( nPos - nOldPos ); + } + + rDo.GetInf().SetUpper( sal_False ); + rDo.GetInf().SetOut( *pOutSize ); + aPartSize = pSmallFont->GetTextSize( rDo.GetInf() ); + nKana += rDo.GetInf().GetKanaDiff(); + rDo.GetInf().SetOut( *pOldOut ); + if( nTmpKern && nPos < nMaxPos ) + aPartSize.Width() += nTmpKern; + rDo.Do(); + nOldPos = nPos; + } + nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharBlock( rOldText, nPos, + pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); + if( nPos == STRING_LEN || nPos > nMaxPos ) + nPos = nMaxPos; + OSL_ENSURE( nPos, "nextCharBlock not implemented?" ); +#if OSL_DEBUG_LEVEL > 1 + if( !nPos ) + nPos = nMaxPos; +#endif + // The upper ones... + if( nOldPos != nPos ) + { + const long nSpaceAdd = rDo.GetInf().GetSpace() / SPACING_PRECISION_FACTOR; + + do + { + rDo.GetInf().SetUpper( sal_True ); + pLastFont = pBigFont; + pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); + xub_StrLen nTmp; + if( bWordWise ) + { + nTmp = nOldPos; + while( nTmp < nPos && CH_BLANK == rOldText.GetChar( nTmp ) ) + ++nTmp; + if( nOldPos < nTmp ) + { + pLastFont = pSpaceFont; + pLastFont->SetDevFont( rDo.GetInf().GetShell(), + rDo.GetOut() ); + ((SwDoDrawCapital&)rDo).DrawSpace( aStartPos ); + pLastFont = pBigFont; + pLastFont->SetDevFont( rDo.GetInf().GetShell(), + rDo.GetOut() ); + + // #107816#, #i14820# + if( bCaseMapLengthDiffers ) + { + // Build an own 'changed' string for the given part of the + // source string and use it. That new string may differ in length + // from the source string. + const XubString aSnippet( rOldText, nOldPos, nTmp - nOldPos); + aNewText = CalcCaseMap( aSnippet ); + aCapInf.nIdx = nOldPos; + aCapInf.nLen = nTmp - nOldPos; + rDo.GetInf().SetIdx( 0 ); + rDo.GetInf().SetLen( aNewText.Len() ); + rDo.GetInf().SetText( aNewText ); + } + else + { + rDo.GetInf().SetIdx( nOldPos ); + rDo.GetInf().SetLen( nTmp - nOldPos ); + } + + rDo.GetInf().SetOut( *pOutSize ); + aPartSize = pBigFont->GetTextSize( rDo.GetInf() ); + nKana += rDo.GetInf().GetKanaDiff(); + rDo.GetInf().SetOut( *pOldOut ); + if( nSpaceAdd ) + aPartSize.Width() += nSpaceAdd * ( nTmp - nOldPos ); + if( nTmpKern && nPos < nMaxPos ) + aPartSize.Width() += nTmpKern; + rDo.Do(); + aStartPos = rDo.GetInf().GetPos(); + nOldPos = nTmp; + } + + while( nTmp < nPos && CH_BLANK != rOldText.GetChar( nTmp ) ) + ++nTmp; + } + else + nTmp = nPos; + if( nTmp > nOldPos ) + { + // #107816#, #i14820# + if( bCaseMapLengthDiffers ) + { + // Build an own 'changed' string for the given part of the + // source string and use it. That new string may differ in length + // from the source string. + const XubString aSnippet( rOldText, nOldPos, nTmp - nOldPos); + aNewText = CalcCaseMap( aSnippet ); + aCapInf.nIdx = nOldPos; + aCapInf.nLen = nTmp - nOldPos; + rDo.GetInf().SetIdx( 0 ); + rDo.GetInf().SetLen( aNewText.Len() ); + rDo.GetInf().SetText( aNewText ); + } + else + { + rDo.GetInf().SetIdx( nOldPos ); + rDo.GetInf().SetLen( nTmp - nOldPos ); + } + + rDo.GetInf().SetOut( *pOutSize ); + aPartSize = pBigFont->GetTextSize( rDo.GetInf() ); + nKana += rDo.GetInf().GetKanaDiff(); + rDo.GetInf().SetOut( *pOldOut ); + if( !bWordWise && rDo.GetInf().GetSpace() ) + { + for( xub_StrLen nI = nOldPos; nI < nPos; ++nI ) + { + if( CH_BLANK == rOldText.GetChar( nI ) ) + aPartSize.Width() += nSpaceAdd; + } + } + if( nTmpKern && nPos < nMaxPos ) + aPartSize.Width() += nTmpKern; + rDo.Do(); + nOldPos = nTmp; + } + } while( nOldPos != nPos ); + } + nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfCharBlock( rOldText, nPos, + pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER); + if( nPos == STRING_LEN || nPos > nMaxPos ) + nPos = nMaxPos; + OSL_ENSURE( nPos, "endOfCharBlock not implemented?" ); +#if OSL_DEBUG_LEVEL > 1 + if( !nPos ) + nPos = nMaxPos; +#endif + } + + // Aufraeumen: + if( pBigFont != pOldLast ) + delete pBigFontAccess; + + if( bTextLines ) + { + if( rDo.GetInf().GetDrawSpace() ) + { + pLastFont = pSpaceFont; + pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); + ( (SwDoDrawCapital&) rDo ).DrawSpace( aStartPos ); + } + if ( bWordWise ) + delete pSpaceFontAccess; + } + pLastFont = pOldLast; + pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() ); + + delete pSmallFontAccess; + rDo.GetInf().SetText( rOldText ); + rDo.GetInf().SetKanaDiff( nKana ); +} + +// JP 22.8.2001 - global optimization off - Bug 91245 / 91223 +#ifdef _MSC_VER +#pragma optimize("g",on) +#endif + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |