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