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