1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <editeng/svxfont.hxx>
22 #include <vcl/outdev.hxx>
23 #include <com/sun/star/i18n/CharType.hpp>
24 #include <com/sun/star/i18n/WordType.hpp>
25 #include <com/sun/star/i18n/XBreakIterator.hpp>
27 #include <fntcache.hxx>
29 #include <breakit.hxx>
31 #include <scriptinfo.hxx>
34 using namespace ::com::sun::star::i18n
;
38 // The information encapsulated in SwCapitalInfo is required
39 // by the ::Do functions. They contain the information about
40 // the original string, whereas rDo.GetInf() contains information
41 // about the display string.
45 explicit SwCapitalInfo( const OUString
& rOrigText
) :
46 rString( rOrigText
), nIdx( 0 ), nLen( 0 ) {};
47 const OUString
& rString
;
54 // rFnt: required for CalcCaseMap
55 // rOrigString: The original string
56 // nOfst: Position of the substring in rOrigString
57 // nLen: Length if the substring in rOrigString
58 // nIdx: Refers to a position in the display string and should be mapped
59 // to a position in rOrigString
60 TextFrameIndex
sw_CalcCaseMap(const SwFont
& rFnt
,
61 const OUString
& rOrigString
,
62 TextFrameIndex
const nOfst
,
63 TextFrameIndex
const nLen
,
64 TextFrameIndex
const nIdx
)
67 const TextFrameIndex nEnd
= nOfst
+ nLen
;
68 OSL_ENSURE( sal_Int32(nEnd
) <= rOrigString
.getLength(), "sw_CalcCaseMap: Wrong parameters" );
70 // special case for title case:
71 const bool bTitle
= SvxCaseMap::Capitalize
== rFnt
.GetCaseMap();
72 for (TextFrameIndex i
= nOfst
; i
< nEnd
; ++i
)
74 OUString
aTmp(rOrigString
.copy(sal_Int32(i
), 1));
77 g_pBreakIt
->GetBreakIter()->isBeginWord(
78 rOrigString
, sal_Int32(i
),
79 g_pBreakIt
->GetLocale( rFnt
.GetLanguage() ),
80 WordType::ANYWORD_IGNOREWHITESPACES
) )
81 aTmp
= rFnt
.GetActualFont().CalcCaseMap( aTmp
);
83 j
+= aTmp
.getLength();
85 if (TextFrameIndex(j
) > nIdx
)
95 SwDrawTextInfo
&m_rInf
;
96 SwCapitalInfo
* m_pCapInf
; // refers to additional information
97 // required by the ::Do function
98 explicit SwDoCapitals ( SwDrawTextInfo
&rInfo
) : m_rInf( rInfo
), m_pCapInf( nullptr ) { }
101 virtual void Init( SwFntObj
*pUpperFont
, SwFntObj
*pLowerFont
) = 0;
102 virtual void Do() = 0;
103 OutputDevice
& GetOut() { return m_rInf
.GetOut(); }
104 SwDrawTextInfo
& GetInf() { return m_rInf
; }
105 SwCapitalInfo
* GetCapInf() const { return m_pCapInf
; }
106 void SetCapInf( SwCapitalInfo
& rNew
) { m_pCapInf
= &rNew
; }
111 class SwDoGetCapitalSize
: public SwDoCapitals
117 explicit SwDoGetCapitalSize( SwDrawTextInfo
&rInfo
) : SwDoCapitals ( rInfo
) { }
118 virtual ~SwDoGetCapitalSize() {}
119 virtual void Init( SwFntObj
*pUpperFont
, SwFntObj
*pLowerFont
) override
;
120 virtual void Do() override
;
121 const Size
& GetSize() const { return m_aTextSize
; }
126 void SwDoGetCapitalSize::Init( SwFntObj
*, SwFntObj
* )
128 m_aTextSize
.setHeight(0);
129 m_aTextSize
.setWidth(0);
132 void SwDoGetCapitalSize::Do()
134 m_aTextSize
.AdjustWidth(m_rInf
.GetSize().Width());
135 if( m_rInf
.GetUpper() )
136 m_aTextSize
.setHeight(m_rInf
.GetSize().Height());
139 Size
SwSubFont::GetCapitalSize( SwDrawTextInfo
& rInf
)
142 const tools::Long nOldKern
= rInf
.GetKern();
143 rInf
.SetKern( CheckKerning() );
144 rInf
.SetPos( Point() );
146 rInf
.SetDrawSpace( false );
147 SwDoGetCapitalSize
aDo( rInf
);
149 Size
aTextSize( aDo
.GetSize() );
152 if( !aTextSize
.Height() )
154 SV_STAT( nGetTextSize
);
155 aTextSize
.setHeight( short ( rInf
.GetpOut()->GetTextHeight() ) );
157 rInf
.SetKern( nOldKern
);
163 class SwDoGetCapitalBreak
: public SwDoCapitals
166 tools::Long m_nTextWidth
;
167 TextFrameIndex m_nBreak
;
170 SwDoGetCapitalBreak(SwDrawTextInfo
& rInfo
, tools::Long
const nWidth
)
171 : SwDoCapitals(rInfo
)
172 , m_nTextWidth(nWidth
)
175 virtual ~SwDoGetCapitalBreak() {}
176 virtual void Init( SwFntObj
*pUpperFont
, SwFntObj
*pLowerFont
) override
;
177 virtual void Do() override
;
178 TextFrameIndex
getBreak() const { return m_nBreak
; }
183 void SwDoGetCapitalBreak::Init( SwFntObj
*, SwFntObj
* )
187 void SwDoGetCapitalBreak::Do()
192 if (m_rInf
.GetSize().Width() < m_nTextWidth
)
193 m_nTextWidth
-= m_rInf
.GetSize().Width();
196 TextFrameIndex nEnd
= m_rInf
.GetEnd();
197 m_nBreak
= TextFrameIndex(GetOut().GetTextBreak(m_rInf
.GetText(), m_nTextWidth
,
198 sal_Int32(m_rInf
.GetIdx()),
199 sal_Int32(m_rInf
.GetLen()), m_rInf
.GetKern()));
201 if (m_nBreak
> nEnd
|| m_nBreak
< TextFrameIndex(0))
204 // m_nBreak may be relative to the display string. It has to be
205 // calculated relative to the original string:
208 if ( GetCapInf()->nLen
!= m_rInf
.GetLen() )
209 m_nBreak
= sw_CalcCaseMap( *m_rInf
.GetFont(),
210 GetCapInf()->rString
,
212 GetCapInf()->nLen
, m_nBreak
);
214 m_nBreak
= m_nBreak
+ GetCapInf()->nIdx
;
221 TextFrameIndex
SwFont::GetCapitalBreak( SwViewShell
const * pSh
, const OutputDevice
* pOut
,
222 const SwScriptInfo
* pScript
, const OUString
& rText
, tools::Long
const nTextWidth
,
223 TextFrameIndex
const nIdx
, TextFrameIndex
const nLen
)
227 SwDrawTextInfo
aInfo(pSh
, *const_cast<OutputDevice
*>(pOut
), pScript
, rText
, nIdx
, nLen
,
229 aInfo
.SetPos( aPos
);
231 aInfo
.SetWrong( nullptr );
232 aInfo
.SetGrammarCheck( nullptr );
233 aInfo
.SetSmartTags( nullptr );
234 aInfo
.SetDrawSpace( false );
235 aInfo
.SetKern( CheckKerning() );
236 aInfo
.SetKanaComp( pScript
? 0 : 100 );
237 aInfo
.SetFont( this );
239 SwDoGetCapitalBreak
aDo(aInfo
, nTextWidth
);
241 return aDo
.getBreak();
246 class SwDoDrawCapital
: public SwDoCapitals
249 SwFntObj
* m_pUpperFnt
;
250 SwFntObj
* m_pLowerFnt
;
253 explicit SwDoDrawCapital(SwDrawTextInfo
& rInfo
)
254 : SwDoCapitals(rInfo
)
255 , m_pUpperFnt(nullptr)
256 , m_pLowerFnt(nullptr)
258 virtual ~SwDoDrawCapital() {}
259 virtual void Init( SwFntObj
*pUpperFont
, SwFntObj
*pLowerFont
) override
;
260 virtual void Do() override
;
261 void DrawSpace( Point
&rPos
);
266 void SwDoDrawCapital::Init( SwFntObj
*pUpperFont
, SwFntObj
*pLowerFont
)
268 m_pUpperFnt
= pUpperFont
;
269 m_pLowerFnt
= pLowerFont
;
272 void SwDoDrawCapital::Do()
274 SV_STAT( nDrawText
);
275 const sal_uInt16 nOrgWidth
= m_rInf
.GetWidth();
276 m_rInf
.SetWidth( sal_uInt16(m_rInf
.GetSize().Width()) );
277 if ( m_rInf
.GetUpper() )
278 m_pUpperFnt
->DrawText(m_rInf
);
281 bool bOldBullet
= m_rInf
.GetBullet();
282 m_rInf
.SetBullet( false );
283 m_pLowerFnt
->DrawText(m_rInf
);
284 m_rInf
.SetBullet( bOldBullet
);
287 OSL_ENSURE(m_pUpperFnt
, "No upper font, dying soon!");
288 m_rInf
.Shift(m_pUpperFnt
->GetFont().GetOrientation());
289 m_rInf
.SetWidth( nOrgWidth
);
292 void SwDoDrawCapital::DrawSpace( Point
&rPos
)
294 tools::Long nDiff
= m_rInf
.GetPos().X() - rPos
.X();
297 const bool bSwitchL2R
= m_rInf
.GetFrame()->IsRightToLeft() &&
298 ! m_rInf
.IsIgnoreFrameRTL();
301 m_rInf
.GetFrame()->SwitchLTRtoRTL( aPos
);
303 const vcl::text::ComplexTextLayoutFlags nMode
= m_rInf
.GetpOut()->GetLayoutMode();
304 const bool bBidiPor
= ( bSwitchL2R
!=
305 ( vcl::text::ComplexTextLayoutFlags::Default
!= ( vcl::text::ComplexTextLayoutFlags::BiDiRtl
& nMode
) ) );
310 if ( m_rInf
.GetFrame()->IsVertical() )
311 m_rInf
.GetFrame()->SwitchHorizontalToVertical( aPos
);
315 m_rInf
.ApplyAutoColor();
316 GetOut().DrawStretchText( aPos
, nDiff
,
319 rPos
.setX( m_rInf
.GetPos().X() + m_rInf
.GetWidth() );
322 void SwSubFont::DrawCapital( SwDrawTextInfo
&rInf
)
324 // Precondition: rInf.GetPos() has already been calculated
326 rInf
.SetDrawSpace( GetUnderline() != LINESTYLE_NONE
||
327 GetOverline() != LINESTYLE_NONE
||
328 GetStrikeout() != STRIKEOUT_NONE
);
329 SwDoDrawCapital
aDo( rInf
);
335 class SwDoCapitalCursorOfst
: public SwDoCapitals
338 SwFntObj
* m_pUpperFnt
;
339 SwFntObj
* m_pLowerFnt
;
340 TextFrameIndex m_nCursor
;
344 SwDoCapitalCursorOfst(SwDrawTextInfo
& rInfo
, const sal_uInt16 nOfs
)
345 : SwDoCapitals(rInfo
)
346 , m_pUpperFnt(nullptr)
347 , m_pLowerFnt(nullptr)
351 virtual ~SwDoCapitalCursorOfst() {}
352 virtual void Init( SwFntObj
*pUpperFont
, SwFntObj
*pLowerFont
) override
;
353 virtual void Do() override
;
355 TextFrameIndex
GetCursor() const { return m_nCursor
; }
360 void SwDoCapitalCursorOfst::Init( SwFntObj
*pUpperFont
, SwFntObj
*pLowerFont
)
362 m_pUpperFnt
= pUpperFont
;
363 m_pLowerFnt
= pLowerFont
;
366 void SwDoCapitalCursorOfst::Do()
371 if (static_cast<tools::Long
>(m_nOfst
) > m_rInf
.GetSize().Width())
373 m_nOfst
-= m_rInf
.GetSize().Width();
374 m_nCursor
= m_nCursor
+ m_rInf
.GetLen();
378 SwDrawTextInfo
aDrawInf( m_rInf
.GetShell(), *m_rInf
.GetpOut(),
379 m_rInf
.GetScriptInfo(),
382 m_rInf
.GetLen(), 0, false );
383 aDrawInf
.SetOffset(m_nOfst
);
384 aDrawInf
.SetKern( m_rInf
.GetKern() );
385 aDrawInf
.SetKanaComp( m_rInf
.GetKanaComp() );
386 aDrawInf
.SetFrame( m_rInf
.GetFrame() );
387 aDrawInf
.SetFont( m_rInf
.GetFont() );
389 if ( m_rInf
.GetUpper() )
391 aDrawInf
.SetSpace( 0 );
392 m_nCursor
= m_nCursor
+ m_pUpperFnt
->GetModelPositionForViewPoint(aDrawInf
);
396 aDrawInf
.SetSpace( m_rInf
.GetSpace() );
397 m_nCursor
= m_nCursor
+ m_pLowerFnt
->GetModelPositionForViewPoint(aDrawInf
);
403 TextFrameIndex
SwSubFont::GetCapitalCursorOfst( SwDrawTextInfo
& rInf
)
405 const tools::Long nOldKern
= rInf
.GetKern();
406 rInf
.SetKern( CheckKerning() );
407 SwDoCapitalCursorOfst
aDo( rInf
, rInf
.GetOffset() );
408 rInf
.SetPos( Point() );
409 rInf
.SetDrawSpace( false );
411 rInf
.SetKern( nOldKern
);
412 return aDo
.GetCursor();
417 class SwDoDrawStretchCapital
: public SwDoDrawCapital
419 const TextFrameIndex m_nStrLen
;
420 const sal_uInt16 m_nCapWidth
;
421 const sal_uInt16 m_nOrgWidth
;
424 virtual void Do() override
;
426 SwDoDrawStretchCapital(SwDrawTextInfo
& rInfo
, const sal_uInt16 nCapitalWidth
)
427 : SwDoDrawCapital(rInfo
)
428 , m_nStrLen(rInfo
.GetLen())
429 , m_nCapWidth(nCapitalWidth
)
430 , m_nOrgWidth(rInfo
.GetWidth())
436 void SwDoDrawStretchCapital::Do()
438 SV_STAT( nDrawStretchText
);
439 tools::Long nPartWidth
= m_rInf
.GetSize().Width();
441 if( m_rInf
.GetLen() )
443 // small caps and kerning
444 tools::Long nDiff
= tools::Long(m_nOrgWidth
) - tools::Long(m_nCapWidth
);
447 nDiff
*= sal_Int32(m_rInf
.GetLen());
448 nDiff
/= sal_Int32(m_nStrLen
);
454 m_rInf
.ApplyAutoColor();
456 Point
aPos( m_rInf
.GetPos() );
457 const bool bSwitchL2R
= m_rInf
.GetFrame()->IsRightToLeft() &&
458 ! m_rInf
.IsIgnoreFrameRTL();
461 m_rInf
.GetFrame()->SwitchLTRtoRTL( aPos
);
463 if ( m_rInf
.GetFrame()->IsVertical() )
464 m_rInf
.GetFrame()->SwitchHorizontalToVertical( aPos
);
467 if (TextFrameIndex(1) >= m_rInf
.GetLen())
468 GetOut().DrawText(aPos
, m_rInf
.GetText(), sal_Int32(m_rInf
.GetIdx()),
469 sal_Int32(m_rInf
.GetLen()));
471 GetOut().DrawStretchText(aPos
, nPartWidth
, m_rInf
.GetText(),
472 sal_Int32(m_rInf
.GetIdx()), sal_Int32(m_rInf
.GetLen()));
474 const_cast<Point
&>(m_rInf
.GetPos()).AdjustX(nPartWidth
);
477 void SwSubFont::DrawStretchCapital( SwDrawTextInfo
&rInf
)
479 // Precondition: rInf.GetPos() has already been calculated
481 if (rInf
.GetLen() == TextFrameIndex(COMPLETE_STRING
))
482 rInf
.SetLen(TextFrameIndex(rInf
.GetText().getLength()));
484 const Point aOldPos
= rInf
.GetPos();
485 const sal_uInt16 nCapWidth
= o3tl::narrowing
<sal_uInt16
>( GetCapitalSize( rInf
).Width() );
486 rInf
.SetPos(aOldPos
);
488 rInf
.SetDrawSpace( GetUnderline() != LINESTYLE_NONE
||
489 GetOverline() != LINESTYLE_NONE
||
490 GetStrikeout() != STRIKEOUT_NONE
);
491 SwDoDrawStretchCapital
aDo( rInf
, nCapWidth
);
495 void SwSubFont::DoOnCapitals( SwDoCapitals
&rDo
)
497 OSL_ENSURE( pLastFont
, "SwFont::DoOnCapitals: No LastFont?!" );
499 tools::Long nKana
= 0;
500 const OUString
aText( CalcCaseMap( rDo
.GetInf().GetText() ) );
501 TextFrameIndex nMaxPos
= std::min(
502 TextFrameIndex(rDo
.GetInf().GetText().getLength()) - rDo
.GetInf().GetIdx(),
503 rDo
.GetInf().GetLen() );
504 rDo
.GetInf().SetLen( nMaxPos
);
506 const OUString oldText
= rDo
.GetInf().GetText();
507 rDo
.GetInf().SetText( aText
);
508 TextFrameIndex nPos
= rDo
.GetInf().GetIdx();
509 TextFrameIndex nOldPos
= nPos
;
510 nMaxPos
= nMaxPos
+ nPos
;
512 // Look if the length of the original text and the ToUpper-converted
513 // text is different. If yes, do special handling.
514 SwCapitalInfo
aCapInf(oldText
);
515 bool bCaseMapLengthDiffers(aText
.getLength() != oldText
.getLength());
516 if ( bCaseMapLengthDiffers
)
517 rDo
.SetCapInf( aCapInf
);
519 SwFntObj
*pOldLast
= pLastFont
;
520 std::optional
<SwFntAccess
> oBigFontAccess
;
522 std::optional
<SwFntAccess
> oSpaceFontAccess
;
523 SwFntObj
*pSpaceFont
= nullptr;
525 const void* nFontCacheId2
= nullptr;
526 sal_uInt16 nIndex2
= 0;
527 SwSubFont
aFont( *this );
528 Point
aStartPos( rDo
.GetInf().GetPos() );
530 const bool bTextLines
= aFont
.GetUnderline() != LINESTYLE_NONE
531 || aFont
.GetOverline() != LINESTYLE_NONE
532 || aFont
.GetStrikeout() != STRIKEOUT_NONE
;
533 const bool bWordWise
= bTextLines
&& aFont
.IsWordLineMode() &&
534 rDo
.GetInf().GetDrawSpace();
535 const tools::Long nTmpKern
= rDo
.GetInf().GetKern();
541 aFont
.SetWordLineMode( false );
542 oSpaceFontAccess
.emplace( nFontCacheId2
, nIndex2
, &aFont
,
543 rDo
.GetInf().GetShell() );
544 pSpaceFont
= oSpaceFontAccess
->Get();
547 pSpaceFont
= pLastFont
;
549 // Construct a font for the capitals:
550 aFont
.SetUnderline( LINESTYLE_NONE
);
551 aFont
.SetOverline( LINESTYLE_NONE
);
552 aFont
.SetStrikeout( STRIKEOUT_NONE
);
553 nFontCacheId2
= nullptr;
555 oBigFontAccess
.emplace( nFontCacheId2
, nIndex2
, &aFont
,
556 rDo
.GetInf().GetShell() );
557 pBigFont
= oBigFontAccess
->Get();
560 pBigFont
= pLastFont
;
562 // Older LO versions had 66 as the small caps percentage size, later changed to 80,
563 // therefore a backwards compatibility option is kept (otherwise layout is changed).
564 // NOTE: There are more uses of SMALL_CAPS_PERCENTAGE in editeng, but it seems they
565 // do not matter for Writer (and if they did it'd be pretty ugly to propagate
566 // the option there).
567 int smallCapsPercentage
= m_bSmallCapsPercentage66
? 66 : SMALL_CAPS_PERCENTAGE
;
568 aFont
.SetProportion( (aFont
.GetPropr() * smallCapsPercentage
) / 100 );
569 nFontCacheId2
= nullptr;
571 std::optional
<SwFntAccess
> oSmallFontAccess( std::in_place
, nFontCacheId2
, nIndex2
, &aFont
,
572 rDo
.GetInf().GetShell() );
573 SwFntObj
*pSmallFont
= oSmallFontAccess
->Get();
575 rDo
.Init( pBigFont
, pSmallFont
);
576 OutputDevice
* pOutSize
= pSmallFont
->GetPrt();
578 pOutSize
= &rDo
.GetOut();
579 OutputDevice
* pOldOut
= &rDo
.GetOut();
581 const LanguageType eLng
= LANGUAGE_DONTKNOW
== GetLanguage()
582 ? LANGUAGE_SYSTEM
: GetLanguage();
586 nPos
= TextFrameIndex(g_pBreakIt
->GetBreakIter()->endOfCharBlock(
587 oldText
, sal_Int32(nPos
),
588 g_pBreakIt
->GetLocale( eLng
), CharType::LOWERCASE_LETTER
));
589 if (nPos
< TextFrameIndex(0))
591 else if( nPos
> nMaxPos
)
595 while( nOldPos
< nMaxPos
)
599 if( nOldPos
!= nPos
)
601 SV_STAT( nGetTextSize
);
602 pLastFont
= pSmallFont
;
603 pLastFont
->SetDevFont( rDo
.GetInf().GetShell(), rDo
.GetOut() );
605 // #107816#, #i14820#
606 if( bCaseMapLengthDiffers
)
608 // Build an own 'changed' string for the given part of the
609 // source string and use it. That new string may differ in length
610 // from the source string.
611 const OUString aNewText
= CalcCaseMap(
612 oldText
.copy(sal_Int32(nOldPos
), sal_Int32(nPos
-nOldPos
)));
613 aCapInf
.nIdx
= nOldPos
;
614 aCapInf
.nLen
= nPos
- nOldPos
;
615 rDo
.GetInf().SetTextIdxLen(aNewText
, TextFrameIndex(0), TextFrameIndex(aNewText
.getLength()));
619 rDo
.GetInf().SetIdxLen(nOldPos
, nPos
- nOldPos
);
622 rDo
.GetInf().SetUpper( false );
623 rDo
.GetInf().SetOut( *pOutSize
);
624 Size aPartSize
= pSmallFont
->GetTextSize( rDo
.GetInf() );
625 nKana
+= rDo
.GetInf().GetKanaDiff();
626 rDo
.GetInf().SetOut( *pOldOut
);
627 if( nTmpKern
&& nPos
< nMaxPos
)
628 aPartSize
.AdjustWidth(nTmpKern
);
629 rDo
.GetInf().SetSize( aPartSize
);
633 nPos
= TextFrameIndex(g_pBreakIt
->GetBreakIter()->nextCharBlock(
634 oldText
, sal_Int32(nPos
),
635 g_pBreakIt
->GetLocale( eLng
), CharType::LOWERCASE_LETTER
));
636 if (nPos
< TextFrameIndex(0) || nPos
> nMaxPos
)
638 OSL_ENSURE( nPos
, "nextCharBlock not implemented?" );
639 #if OSL_DEBUG_LEVEL > 1
644 if( nOldPos
!= nPos
)
646 const tools::Long nSpaceAdd
= rDo
.GetInf().GetSpace() / SPACING_PRECISION_FACTOR
;
650 rDo
.GetInf().SetUpper( true );
651 pLastFont
= pBigFont
;
652 pLastFont
->SetDevFont( rDo
.GetInf().GetShell(), rDo
.GetOut() );
657 while (nTmp
< nPos
&& CH_BLANK
== oldText
[sal_Int32(nTmp
)])
661 pLastFont
= pSpaceFont
;
662 pLastFont
->SetDevFont( rDo
.GetInf().GetShell(),
664 static_cast<SwDoDrawCapital
&>(rDo
).DrawSpace( aStartPos
);
665 pLastFont
= pBigFont
;
666 pLastFont
->SetDevFont( rDo
.GetInf().GetShell(),
669 // #107816#, #i14820#
670 if( bCaseMapLengthDiffers
)
672 // Build an own 'changed' string for the given part of the
673 // source string and use it. That new string may differ in length
674 // from the source string.
675 const OUString aNewText
= CalcCaseMap(
676 oldText
.copy(sal_Int32(nOldPos
), sal_Int32(nTmp
-nOldPos
)));
677 aCapInf
.nIdx
= nOldPos
;
678 aCapInf
.nLen
= nTmp
- nOldPos
;
679 rDo
.GetInf().SetIdx(TextFrameIndex(0));
680 rDo
.GetInf().SetLen(TextFrameIndex(aNewText
.getLength()));
681 rDo
.GetInf().SetText( aNewText
);
685 rDo
.GetInf().SetIdx( nOldPos
);
686 rDo
.GetInf().SetLen( nTmp
- nOldPos
);
689 rDo
.GetInf().SetOut( *pOutSize
);
690 Size aPartSize
= pBigFont
->GetTextSize( rDo
.GetInf() );
691 nKana
+= rDo
.GetInf().GetKanaDiff();
692 rDo
.GetInf().SetOut( *pOldOut
);
694 aPartSize
.AdjustWidth(nSpaceAdd
* sal_Int32(nTmp
- nOldPos
));
695 if( nTmpKern
&& nPos
< nMaxPos
)
696 aPartSize
.AdjustWidth(nTmpKern
);
697 rDo
.GetInf().SetSize( aPartSize
);
699 aStartPos
= rDo
.GetInf().GetPos();
703 while (nTmp
< nPos
&& CH_BLANK
!= oldText
[sal_Int32(nTmp
)])
710 // #107816#, #i14820#
711 if( bCaseMapLengthDiffers
)
713 // Build an own 'changed' string for the given part of the
714 // source string and use it. That new string may differ in length
715 // from the source string.
716 const OUString aNewText
= CalcCaseMap(
717 oldText
.copy(sal_Int32(nOldPos
), sal_Int32(nTmp
-nOldPos
)));
718 aCapInf
.nIdx
= nOldPos
;
719 aCapInf
.nLen
= nTmp
- nOldPos
;
720 rDo
.GetInf().SetTextIdxLen( aNewText
, TextFrameIndex(0), TextFrameIndex(aNewText
.getLength()));
724 rDo
.GetInf().SetIdxLen( nOldPos
, nTmp
- nOldPos
);
727 rDo
.GetInf().SetOut( *pOutSize
);
728 Size aPartSize
= pBigFont
->GetTextSize( rDo
.GetInf() );
729 nKana
+= rDo
.GetInf().GetKanaDiff();
730 rDo
.GetInf().SetOut( *pOldOut
);
731 if( !bWordWise
&& rDo
.GetInf().GetSpace() )
733 for (TextFrameIndex nI
= nOldPos
; nI
< nPos
; ++nI
)
735 if (CH_BLANK
== oldText
[sal_Int32(nI
)])
736 aPartSize
.AdjustWidth(nSpaceAdd
);
739 if( nTmpKern
&& nPos
< nMaxPos
)
740 aPartSize
.AdjustWidth(nTmpKern
);
741 rDo
.GetInf().SetSize( aPartSize
);
745 } while( nOldPos
!= nPos
);
747 nPos
= TextFrameIndex(g_pBreakIt
->GetBreakIter()->endOfCharBlock(
748 oldText
, sal_Int32(nPos
),
749 g_pBreakIt
->GetLocale( eLng
), CharType::LOWERCASE_LETTER
));
750 if (nPos
< TextFrameIndex(0) || nPos
> nMaxPos
)
752 OSL_ENSURE( nPos
, "endOfCharBlock not implemented?" );
753 #if OSL_DEBUG_LEVEL > 1
760 if( pBigFont
!= pOldLast
)
761 oBigFontAccess
.reset();
765 if( rDo
.GetInf().GetDrawSpace() )
767 pLastFont
= pSpaceFont
;
768 pLastFont
->SetDevFont( rDo
.GetInf().GetShell(), rDo
.GetOut() );
769 static_cast<SwDoDrawCapital
&>( rDo
).DrawSpace( aStartPos
);
772 oSpaceFontAccess
.reset();
774 pLastFont
= pOldLast
;
775 pLastFont
->SetDevFont( rDo
.GetInf().GetShell(), rDo
.GetOut() );
777 oSmallFontAccess
.reset();
778 rDo
.GetInf().SetText(oldText
);
779 rDo
.GetInf().SetKanaDiff( nKana
);
782 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */