LCOV - code coverage report
Current view: top level - editeng/source/items - svxfont.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 134 357 37.5 %
Date: 2015-06-13 12:38:46 Functions: 11 37 29.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <comphelper/string.hxx>
      21             : #include <vcl/outdev.hxx>
      22             : #include <vcl/print.hxx>
      23             : #include <tools/gen.hxx>
      24             : #include <tools/poly.hxx>
      25             : #include <unotools/charclass.hxx>
      26             : #include <editeng/unolingu.hxx>
      27             : #include <com/sun/star/i18n/KCharacterType.hpp>
      28             : #include <editeng/svxfont.hxx>
      29             : #include <editeng/escapementitem.hxx>
      30             : 
      31             : const sal_Unicode CH_BLANK = ' ';  // ' ' Space character
      32             : 
      33             : 
      34     2668970 : SvxFont::SvxFont()
      35             : {
      36     2668970 :     nKern = nEsc = 0;
      37     2668970 :     nPropr = 100;
      38     2668970 :     eCaseMap = SVX_CASEMAP_NOT_MAPPED;
      39     2668970 :     SetLanguage(LANGUAGE_SYSTEM);
      40     2668970 : }
      41             : 
      42        1649 : SvxFont::SvxFont( const vcl::Font &rFont )
      43        1649 :     : Font( rFont )
      44             : {
      45        1649 :     nKern = nEsc = 0;
      46        1649 :     nPropr = 100;
      47        1649 :     eCaseMap = SVX_CASEMAP_NOT_MAPPED;
      48        1649 :     SetLanguage(LANGUAGE_SYSTEM);
      49        1649 : }
      50             : 
      51      164504 : SvxFont::SvxFont( const SvxFont &rFont )
      52      164504 :     : Font( rFont )
      53             : {
      54      164504 :     nKern = rFont.GetFixKerning();
      55      164504 :     nEsc  = rFont.GetEscapement();
      56      164504 :     nPropr = rFont.GetPropr();
      57      164504 :     eCaseMap = rFont.GetCaseMap();
      58      164504 :     SetLanguage(rFont.GetLanguage());
      59      164504 : }
      60             : 
      61         461 : void SvxFont::DrawArrow( OutputDevice &rOut, const Rectangle& rRect,
      62             :     const Size& rSize, const Color& rCol, bool bLeft )
      63             : {
      64         461 :     long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2;
      65         461 :     long nRight = nLeft + rSize.Width();
      66         461 :     long nMid = ( rRect.Top() + rRect.Bottom() ) / 2;
      67         461 :     long nTop = nMid - rSize.Height() / 2;
      68         461 :     long nBottom = nTop + rSize.Height();
      69         461 :     if( nLeft < rRect.Left() )
      70             :     {
      71         282 :         nLeft = rRect.Left();
      72         282 :         nRight = rRect.Right();
      73             :     }
      74         461 :     if( nTop < rRect.Top() )
      75             :     {
      76           0 :         nTop = rRect.Top();
      77           0 :         nBottom = rRect.Bottom();
      78             :     }
      79         461 :     Polygon aPoly;
      80         461 :     Point aTmp( bLeft ? nLeft : nRight, nMid );
      81         461 :     Point aNxt( bLeft ? nRight : nLeft, nTop );
      82         461 :     aPoly.Insert( 0, aTmp );
      83         461 :     aPoly.Insert( 0, aNxt );
      84         461 :     aNxt.Y() = nBottom;
      85         461 :     aPoly.Insert( 0, aNxt );
      86         461 :     aPoly.Insert( 0, aTmp );
      87         461 :     Color aOldLineColor = rOut.GetLineColor();
      88         461 :     Color aOldFillColor = rOut.GetFillColor();
      89         461 :     rOut.SetFillColor( rCol );
      90         461 :     rOut.SetLineColor( Color( COL_BLACK ) );
      91         461 :     rOut.DrawPolygon( aPoly );
      92         461 :     rOut.DrawLine( aTmp, aNxt );
      93         461 :     rOut.SetLineColor( aOldLineColor );
      94         461 :     rOut.SetFillColor( aOldFillColor );
      95         461 : }
      96             : 
      97             : 
      98       28190 : OUString SvxFont::CalcCaseMap(const OUString &rTxt) const
      99             : {
     100       28190 :     if (!IsCaseMap() || rTxt.isEmpty())
     101       22030 :         return rTxt;
     102        6160 :     OUString aTxt(rTxt);
     103             :     // I still have to get the language
     104        6160 :     const LanguageType eLang = LANGUAGE_DONTKNOW == GetLanguage()
     105        6160 :                              ? LANGUAGE_SYSTEM : GetLanguage();
     106             : 
     107       12320 :     LanguageTag aLanguageTag(eLang);
     108       12320 :     CharClass aCharClass( aLanguageTag );
     109             : 
     110        6160 :     switch( eCaseMap )
     111             :     {
     112             :         case SVX_CASEMAP_KAPITAELCHEN:
     113             :         case SVX_CASEMAP_VERSALIEN:
     114             :         {
     115        3136 :             aTxt = aCharClass.uppercase( aTxt );
     116        3136 :             break;
     117             :         }
     118             : 
     119             :         case SVX_CASEMAP_GEMEINE:
     120             :         {
     121        2261 :             aTxt = aCharClass.lowercase( aTxt );
     122        2261 :             break;
     123             :         }
     124             :         case SVX_CASEMAP_TITEL:
     125             :         {
     126             :             // Every beginning of a word is capitalized,  the rest of the word
     127             :             // is taken over as is.
     128             :             // Bug: if the attribute starts in the middle of the word.
     129         763 :             bool bBlank = true;
     130             : 
     131        9390 :             for (sal_Int32 i = 0; i < aTxt.getLength(); ++i)
     132             :             {
     133        8627 :                 if( aTxt[i] == ' ' || aTxt[i] == '\t')
     134         685 :                     bBlank = true;
     135             :                 else
     136             :                 {
     137        7942 :                     if (bBlank)
     138             :                     {
     139        1448 :                         OUString sTitle(aCharClass.uppercase(OUString(aTxt[i])));
     140        1448 :                         aTxt = aTxt.replaceAt(i, 1, sTitle);
     141             :                     }
     142        7942 :                     bBlank = false;
     143             :                 }
     144             :             }
     145         763 :             break;
     146             :         }
     147             :         default:
     148             :         {
     149             :             DBG_ASSERT(false, "SvxFont::CaseMapTxt: unknown casemap");
     150           0 :             break;
     151             :         }
     152             :     }
     153       12320 :     return aTxt;
     154             : }
     155             : 
     156             : /*************************************************************************
     157             :  *                      class SvxDoCapitals
     158             :  * The virtual Method Do si called by SvxFont::DoOnCapitals alternately
     159             :  * the uppercase and lowercase parts. The derivate of SvxDoCapitals fills
     160             :  * this method with life.
     161             :  *************************************************************************/
     162             : 
     163             : class SvxDoCapitals
     164             : {
     165             : protected:
     166             :     VclPtr<OutputDevice> pOut;
     167             :     const OUString &rTxt;
     168             :     const sal_Int32 nIdx;
     169             :     const sal_Int32 nLen;
     170             : 
     171             : public:
     172           0 :     SvxDoCapitals( OutputDevice *_pOut, const OUString &_rTxt,
     173             :                    const sal_Int32 _nIdx, const sal_Int32 _nLen )
     174           0 :         : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen)
     175           0 :         { }
     176             : 
     177           0 :     virtual ~SvxDoCapitals() {}
     178             : 
     179             :     virtual void DoSpace( const bool bDraw );
     180             :     virtual void SetSpace();
     181             :     virtual void Do( const OUString &rTxt,
     182             :                      const sal_Int32 nIdx, const sal_Int32 nLen,
     183             :                      const bool bUpper ) = 0;
     184             : 
     185           0 :     const OUString &GetTxt() const { return rTxt; }
     186           0 :     sal_Int32 GetIdx() const { return nIdx; }
     187           0 :     sal_Int32 GetLen() const { return nLen; }
     188             : };
     189             : 
     190           0 : void SvxDoCapitals::DoSpace( const bool /*bDraw*/ ) { }
     191             : 
     192           0 : void SvxDoCapitals::SetSpace() { }
     193             : 
     194             : /*************************************************************************
     195             :  *                  SvxFont::DoOnCapitals() const
     196             :  * Decomposes the String into uppercase and lowercase letters and then
     197             :  * calls the method SvxDoCapitals::Do( ).
     198             :  *************************************************************************/
     199             : 
     200           0 : void SvxFont::DoOnCapitals(SvxDoCapitals &rDo) const
     201             : {
     202           0 :     const OUString &rTxt = rDo.GetTxt();
     203           0 :     const sal_Int32 nIdx = rDo.GetIdx();
     204           0 :     const sal_Int32 nLen = rDo.GetLen();
     205             : 
     206           0 :     const OUString aTxt( CalcCaseMap( rTxt ) );
     207           0 :     const sal_Int32 nTxtLen = std::min( rTxt.getLength(), nLen );
     208           0 :     sal_Int32 nPos = 0;
     209           0 :     sal_Int32 nOldPos = nPos;
     210             : 
     211             :     // #108210#
     212             :     // Test if string length differ between original and CaseMapped
     213           0 :     bool bCaseMapLengthDiffers(aTxt.getLength() != rTxt.getLength());
     214             : 
     215           0 :     const LanguageType eLang = LANGUAGE_DONTKNOW == GetLanguage()
     216           0 :                              ? LANGUAGE_SYSTEM : GetLanguage();
     217             : 
     218           0 :     LanguageTag aLanguageTag(eLang);
     219           0 :     CharClass   aCharClass( aLanguageTag );
     220           0 :     OUString    aCharString;
     221             : 
     222           0 :     while( nPos < nTxtLen )
     223             :     {
     224             :         // first in turn are the uppercase letters
     225             : 
     226             :         // There are characters that are both upper- and lower-case L (eg blank)
     227             :         // Such ambiguities lead to chaos, this is why these characters are
     228             :         // allocated to the lowercase characters!
     229             : 
     230           0 :         while( nPos < nTxtLen )
     231             :         {
     232           0 :             aCharString = rTxt.copy( nPos + nIdx, 1 );
     233           0 :             sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
     234           0 :             if ( nCharacterType & ::com::sun::star::i18n::KCharacterType::LOWER )
     235           0 :                 break;
     236           0 :             if ( ! ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
     237           0 :                 break;
     238           0 :             ++nPos;
     239             :         }
     240           0 :         if( nOldPos != nPos )
     241             :         {
     242           0 :             if(bCaseMapLengthDiffers)
     243             :             {
     244             :                 // #108210#
     245             :                 // If strings differ work preparing the necessary snippet to address that
     246             :                 // potential difference
     247           0 :                 const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos-nOldPos);
     248           0 :                 OUString aNewText = CalcCaseMap(aSnippet);
     249             : 
     250           0 :                 rDo.Do( aNewText, 0, aNewText.getLength(), true );
     251             :             }
     252             :             else
     253             :             {
     254           0 :                 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, true );
     255             :             }
     256             : 
     257           0 :             nOldPos = nPos;
     258             :         }
     259             :         // Now the lowercase are processed (without blanks)
     260           0 :         while( nPos < nTxtLen )
     261             :         {
     262           0 :             sal_uInt32  nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
     263           0 :             if ( ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
     264           0 :                 break;
     265           0 :             if ( comphelper::string::equals(aCharString, CH_BLANK) )
     266           0 :                 break;
     267           0 :             if( ++nPos < nTxtLen )
     268           0 :                 aCharString = rTxt.copy( nPos + nIdx, 1 );
     269             :         }
     270           0 :         if( nOldPos != nPos )
     271             :         {
     272           0 :             if(bCaseMapLengthDiffers)
     273             :             {
     274             :                 // #108210#
     275             :                 // If strings differ work preparing the necessary snippet to address that
     276             :                 // potential difference
     277           0 :                 const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos - nOldPos);
     278           0 :                 OUString aNewText = CalcCaseMap(aSnippet);
     279             : 
     280           0 :                 rDo.Do( aNewText, 0, aNewText.getLength(), false );
     281             :             }
     282             :             else
     283             :             {
     284           0 :                 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, false );
     285             :             }
     286             : 
     287           0 :             nOldPos = nPos;
     288             :         }
     289             :         // Now the blanks are<processed
     290           0 :         while( nPos < nTxtLen && comphelper::string::equals(aCharString, CH_BLANK) && ++nPos < nTxtLen )
     291           0 :             aCharString = rTxt.copy( nPos + nIdx, 1 );
     292             : 
     293           0 :         if( nOldPos != nPos )
     294             :         {
     295           0 :             rDo.DoSpace( false );
     296             : 
     297           0 :             if(bCaseMapLengthDiffers)
     298             :             {
     299             :                 // #108210#
     300             :                 // If strings differ work preparing the necessary snippet to address that
     301             :                 // potential difference
     302           0 :                 const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos - nOldPos);
     303           0 :                 OUString aNewText = CalcCaseMap(aSnippet);
     304             : 
     305           0 :                 rDo.Do( aNewText, 0, aNewText.getLength(), false );
     306             :             }
     307             :             else
     308             :             {
     309           0 :                 rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, false );
     310             :             }
     311             : 
     312           0 :             nOldPos = nPos;
     313           0 :             rDo.SetSpace();
     314             :         }
     315             :     }
     316           0 :     rDo.DoSpace( true );
     317           0 : }
     318             : 
     319             : 
     320      745275 : void SvxFont::SetPhysFont( OutputDevice *pOut ) const
     321             : {
     322      745275 :     const vcl::Font& rCurrentFont = pOut->GetFont();
     323      745275 :     if ( nPropr == 100 )
     324             :     {
     325      738254 :         if ( !rCurrentFont.IsSameInstance( *this ) )
     326      613502 :             pOut->SetFont( *this );
     327             :     }
     328             :     else
     329             :     {
     330        7021 :         Font aNewFont( *this );
     331        7021 :         Size aSize( aNewFont.GetSize() );
     332        7021 :         aNewFont.SetSize( Size( aSize.Width() * nPropr / 100L,
     333       14042 :                                     aSize.Height() * nPropr / 100L ) );
     334        7021 :         if ( !rCurrentFont.IsSameInstance( aNewFont ) )
     335        7021 :             pOut->SetFont( aNewFont );
     336             :     }
     337      745275 : }
     338             : 
     339             : 
     340           0 : vcl::Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const
     341             : {
     342           0 :     vcl::Font aOldFont( pOut->GetFont() );
     343           0 :     SetPhysFont( pOut );
     344           0 :     return aOldFont;
     345             : }
     346             : 
     347             : 
     348           0 : Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const OUString &rTxt,
     349             :                          const sal_Int32 nIdx, const sal_Int32 nLen ) const
     350             : {
     351           0 :     if ( !IsCaseMap() && !IsKern() )
     352             :         return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ),
     353           0 :                      pOut->GetTextHeight() );
     354             : 
     355           0 :     Size aTxtSize;
     356           0 :     aTxtSize.setHeight( pOut->GetTextHeight() );
     357           0 :     if ( !IsCaseMap() )
     358           0 :         aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) );
     359             :     else
     360             :     {
     361             :         // #108210#
     362           0 :         const OUString aNewText = CalcCaseMap(rTxt);
     363           0 :         bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength());
     364           0 :         sal_Int32 nWidth(0L);
     365             : 
     366           0 :         if(bCaseMapLengthDiffers)
     367             :         {
     368             :             // If strings differ work preparing the necessary snippet to address that
     369             :             // potential difference
     370           0 :             const OUString aSnippet = rTxt.copy(nIdx, nLen);
     371           0 :             OUString _aNewText = CalcCaseMap(aSnippet);
     372           0 :             nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.getLength() );
     373             :         }
     374             :         else
     375             :         {
     376           0 :             nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen );
     377             :         }
     378             : 
     379           0 :         aTxtSize.setWidth(nWidth);
     380             :     }
     381             : 
     382           0 :     if( IsKern() && ( nLen > 1 ) )
     383           0 :         aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
     384             : 
     385           0 :     return aTxtSize;
     386             : }
     387             : 
     388      243454 : Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const OUString &rTxt )
     389             : {
     390      243454 :     if ( !IsCaseMap() && !IsKern() )
     391      243187 :         return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() );
     392             : 
     393         267 :     Size aTxtSize;
     394         267 :     aTxtSize.setHeight( pOut->GetTextHeight() );
     395         267 :     if ( !IsCaseMap() )
     396           6 :         aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) );
     397             :     else
     398         261 :         aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) );
     399             : 
     400         267 :     if( IsKern() && ( rTxt.getLength() > 1 ) )
     401           0 :         aTxtSize.Width() += ( ( rTxt.getLength()-1 ) * long( nKern ) );
     402             : 
     403         267 :     return aTxtSize;
     404             : }
     405             : 
     406      233181 : Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt,
     407             :                          const sal_Int32 nIdx, const sal_Int32 nLen, long* pDXArray ) const
     408             : {
     409      233181 :     if ( !IsCaseMap() && !IsKern() )
     410             :         return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ),
     411      224188 :                      pOut->GetTextHeight() );
     412             : 
     413        8993 :     Size aTxtSize;
     414        8993 :     aTxtSize.setHeight( pOut->GetTextHeight() );
     415        8993 :     if ( !IsCaseMap() )
     416        4761 :         aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
     417             :     else
     418             :         aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
     419        4232 :                            pDXArray, nIdx, nLen ) );
     420             : 
     421        8993 :     if( IsKern() && ( nLen > 1 ) )
     422             :     {
     423        5262 :         aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
     424             : 
     425        5262 :         if ( pDXArray )
     426             :         {
     427       44029 :             for ( sal_Int32 i = 0; i < nLen; i++ )
     428       38947 :                 pDXArray[i] += ( (i+1) * long( nKern ) );
     429             :             // The last one is a nKern too big:
     430        5082 :             pDXArray[nLen-1] -= nKern;
     431             :         }
     432             :     }
     433        8993 :     return aTxtSize;
     434             : }
     435             : 
     436             : 
     437           0 : Size SvxFont::GetTextSize( const OutputDevice *pOut, const OUString &rTxt,
     438             :                          const sal_Int32 nIdx, const sal_Int32 nLen ) const
     439             : {
     440           0 :     sal_Int32 nTmp = nLen;
     441           0 :     if ( nTmp == SAL_MAX_INT32 )   // already initialized?
     442           0 :         nTmp = rTxt.getLength();
     443           0 :     Font aOldFont( ChgPhysFont(const_cast<OutputDevice *>(pOut)) );
     444           0 :     Size aTxtSize;
     445           0 :     if( IsCapital() && !rTxt.isEmpty() )
     446             :     {
     447           0 :         aTxtSize = GetCapitalSize( pOut, rTxt, nIdx, nTmp );
     448             :     }
     449           0 :     else aTxtSize = GetPhysTxtSize(pOut,rTxt,nIdx,nTmp);
     450           0 :     const_cast<OutputDevice *>(pOut)->SetFont( aOldFont );
     451           0 :     return aTxtSize;
     452             : }
     453             : 
     454             : 
     455        2813 : void SvxFont::QuickDrawText( OutputDevice *pOut,
     456             :     const Point &rPos, const OUString &rTxt,
     457             :     const sal_Int32 nIdx, const sal_Int32 nLen, const long* pDXArray ) const
     458             : {
     459             : 
     460             :     // Font has to be selected in OutputDevice...
     461        2813 :     if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
     462             :     {
     463        2663 :         pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen );
     464        5476 :         return;
     465             :     }
     466             : 
     467         150 :     Point aPos( rPos );
     468             : 
     469         150 :     if ( nEsc )
     470             :     {
     471         150 :         long nDiff = GetSize().Height();
     472         150 :         nDiff *= nEsc;
     473         150 :         nDiff /= 100;
     474             : 
     475         150 :         if ( !IsVertical() )
     476         150 :             aPos.Y() -= nDiff;
     477             :         else
     478           0 :             aPos.X() += nDiff;
     479             :     }
     480             : 
     481         150 :     if( IsCapital() )
     482             :     {
     483             :         DBG_ASSERT( !pDXArray, "DrawCapital not for TextArray!" );
     484           0 :         DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
     485             :     }
     486             :     else
     487             :     {
     488         150 :         if ( IsKern() && !pDXArray )
     489             :         {
     490           0 :             Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
     491             : 
     492           0 :             if ( !IsCaseMap() )
     493           0 :                 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
     494             :             else
     495           0 :                 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
     496             :         }
     497             :         else
     498             :         {
     499         150 :             if ( !IsCaseMap() )
     500           9 :                 pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
     501             :             else
     502         141 :                 pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen );
     503             :         }
     504             :     }
     505             : }
     506             : 
     507             : 
     508           0 : void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter,
     509             :                         const Point &rPos, const OUString &rTxt,
     510             :                         const sal_Int32 nIdx, const sal_Int32 nLen ) const
     511             : {
     512           0 :     if ( !nLen || rTxt.isEmpty() )
     513           0 :         return;
     514           0 :     sal_Int32 nTmp = nLen;
     515             : 
     516           0 :     if ( nTmp == SAL_MAX_INT32 )   // already initialized?
     517           0 :         nTmp = rTxt.getLength();
     518           0 :     Point aPos( rPos );
     519             : 
     520           0 :     if ( nEsc )
     521             :     {
     522             :         short nTmpEsc;
     523           0 :         if( DFLT_ESC_AUTO_SUPER == nEsc )
     524           0 :             nTmpEsc = 33;
     525           0 :         else if( DFLT_ESC_AUTO_SUB == nEsc )
     526           0 :             nTmpEsc = -20;
     527             :         else
     528           0 :             nTmpEsc = nEsc;
     529           0 :         Size aSize = ( this->GetSize() );
     530           0 :         aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L );
     531             :     }
     532           0 :     Font aOldFont( ChgPhysFont( pOut ) );
     533           0 :     Font aOldPrnFont( ChgPhysFont( pPrinter ) );
     534             : 
     535           0 :     if ( IsCapital() )
     536           0 :         DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
     537             :     else
     538             :     {
     539           0 :         Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
     540             : 
     541           0 :         if ( !IsCaseMap() )
     542           0 :             pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
     543             :         else
     544             :         {
     545             :             // #108210#
     546           0 :             const OUString aNewText = CalcCaseMap(rTxt);
     547           0 :             bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength());
     548             : 
     549           0 :             if(bCaseMapLengthDiffers)
     550             :             {
     551             :                 // If strings differ work preparing the necessary snippet to address that
     552             :                 // potential difference
     553           0 :                 const OUString aSnippet(rTxt.copy( nIdx, nTmp));
     554           0 :                 OUString _aNewText = CalcCaseMap(aSnippet);
     555             : 
     556           0 :                 pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.getLength() );
     557             :             }
     558             :             else
     559             :             {
     560           0 :                 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp );
     561           0 :             }
     562             :         }
     563             :     }
     564           0 :     pOut->SetFont(aOldFont);
     565           0 :     pPrinter->SetFont( aOldPrnFont );
     566             : }
     567             : 
     568             : 
     569      980796 : SvxFont& SvxFont::operator=( const vcl::Font& rFont )
     570             : {
     571      980796 :     Font::operator=( rFont );
     572      980796 :     return *this;
     573             : }
     574             : 
     575     2873695 : SvxFont& SvxFont::operator=( const SvxFont& rFont )
     576             : {
     577     2873695 :     Font::operator=( rFont );
     578     2873695 :     eCaseMap = rFont.eCaseMap;
     579     2873695 :     nEsc = rFont.nEsc;
     580     2873695 :     nPropr = rFont.nPropr;
     581     2873695 :     nKern = rFont.nKern;
     582     2873695 :     return *this;
     583             : }
     584             : 
     585             : class SvxDoGetCapitalSize : public SvxDoCapitals
     586             : {
     587             : protected:
     588             :     SvxFont*    pFont;
     589             :     Size        aTxtSize;
     590             :     short       nKern;
     591             : public:
     592           0 :       SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut,
     593             :                            const OUString &_rTxt, const sal_Int32 _nIdx,
     594             :                            const sal_Int32 _nLen, const short _nKrn )
     595             :             : SvxDoCapitals( const_cast<OutputDevice*>(_pOut), _rTxt, _nIdx, _nLen ),
     596             :               pFont( _pFnt ),
     597           0 :               nKern( _nKrn )
     598           0 :             { }
     599             : 
     600           0 :     virtual ~SvxDoGetCapitalSize() {}
     601             : 
     602             :     virtual void Do( const OUString &rTxt, const sal_Int32 nIdx,
     603             :                      const sal_Int32 nLen, const bool bUpper ) SAL_OVERRIDE;
     604             : 
     605           0 :     const Size &GetSize() const { return aTxtSize; };
     606             : };
     607             : 
     608           0 : void SvxDoGetCapitalSize::Do( const OUString &_rTxt, const sal_Int32 _nIdx,
     609             :                               const sal_Int32 _nLen, const bool bUpper )
     610             : {
     611           0 :     Size aPartSize;
     612           0 :     if ( !bUpper )
     613             :     {
     614           0 :         sal_uInt8 nProp = pFont->GetPropr();
     615           0 :         pFont->SetProprRel( SMALL_CAPS_PERCENTAGE );
     616           0 :         pFont->SetPhysFont( pOut );
     617           0 :         aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
     618           0 :         aPartSize.setHeight( pOut->GetTextHeight() );
     619           0 :         aTxtSize.Height() = aPartSize.Height();
     620           0 :         pFont->SetPropr( nProp );
     621           0 :         pFont->SetPhysFont( pOut );
     622             :     }
     623             :     else
     624             :     {
     625           0 :         aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
     626           0 :         aPartSize.setHeight( pOut->GetTextHeight() );
     627             :     }
     628           0 :     aTxtSize.Width() += aPartSize.Width();
     629           0 :     aTxtSize.Width() += ( _nLen * long( nKern ) );
     630           0 : }
     631             : 
     632           0 : Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt,
     633             :                              const sal_Int32 nIdx, const sal_Int32 nLen) const
     634             : {
     635             :     // Start:
     636           0 :     SvxDoGetCapitalSize aDo( const_cast<SvxFont *>(this), pOut, rTxt, nIdx, nLen, nKern );
     637           0 :     DoOnCapitals( aDo );
     638           0 :     Size aTxtSize( aDo.GetSize() );
     639             : 
     640             :     // End:
     641           0 :     if( !aTxtSize.Height() )
     642             :     {
     643           0 :         aTxtSize.setWidth( 0 );
     644           0 :         aTxtSize.setHeight( pOut->GetTextHeight() );
     645             :     }
     646           0 :     return aTxtSize;
     647             : }
     648             : 
     649           0 : class SvxDoDrawCapital : public SvxDoCapitals
     650             : {
     651             : protected:
     652             :     SvxFont *pFont;
     653             :     Point aPos;
     654             :     Point aSpacePos;
     655             :     short nKern;
     656             : public:
     657           0 :     SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const OUString &_rTxt,
     658             :                       const sal_Int32 _nIdx, const sal_Int32 _nLen,
     659             :                       const Point &rPos, const short nKrn )
     660             :         : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ),
     661             :           pFont( pFnt ),
     662             :           aPos( rPos ),
     663             :           aSpacePos( rPos ),
     664           0 :           nKern( nKrn )
     665           0 :         { }
     666             :     virtual void DoSpace( const bool bDraw ) SAL_OVERRIDE;
     667             :     virtual void SetSpace() SAL_OVERRIDE;
     668             :     virtual void Do( const OUString &rTxt, const sal_Int32 nIdx,
     669             :                      const sal_Int32 nLen, const bool bUpper ) SAL_OVERRIDE;
     670             : };
     671             : 
     672           0 : void SvxDoDrawCapital::DoSpace( const bool bDraw )
     673             : {
     674           0 :     if ( bDraw || pFont->IsWordLineMode() )
     675             :     {
     676           0 :         sal_uLong nDiff = (sal_uLong)(aPos.X() - aSpacePos.X());
     677           0 :         if ( nDiff )
     678             :         {
     679           0 :             bool bWordWise = pFont->IsWordLineMode();
     680           0 :             bool bTrans = pFont->IsTransparent();
     681           0 :             pFont->SetWordLineMode( false );
     682           0 :             pFont->SetTransparent( true );
     683           0 :             pFont->SetPhysFont( pOut );
     684           0 :             pOut->DrawStretchText( aSpacePos, nDiff, "  ", 0, 2 );
     685           0 :             pFont->SetWordLineMode( bWordWise );
     686           0 :             pFont->SetTransparent( bTrans );
     687           0 :             pFont->SetPhysFont( pOut );
     688             :         }
     689             :     }
     690           0 : }
     691             : 
     692           0 : void SvxDoDrawCapital::SetSpace()
     693             : {
     694           0 :     if ( pFont->IsWordLineMode() )
     695           0 :         aSpacePos.X() = aPos.X();
     696           0 : }
     697             : 
     698           0 : void SvxDoDrawCapital::Do( const OUString &_rTxt, const sal_Int32 _nIdx,
     699             :                            const sal_Int32 _nLen, const bool bUpper)
     700             : {
     701           0 :     sal_uInt8 nProp = 0;
     702           0 :     Size aPartSize;
     703             : 
     704             :     // Set the desired font
     705           0 :     FontUnderline eUnder = pFont->GetUnderline();
     706           0 :     FontStrikeout eStrike = pFont->GetStrikeout();
     707           0 :     pFont->SetUnderline( UNDERLINE_NONE );
     708           0 :     pFont->SetStrikeout( STRIKEOUT_NONE );
     709           0 :     if ( !bUpper )
     710             :     {
     711           0 :         nProp = pFont->GetPropr();
     712           0 :         pFont->SetProprRel( SMALL_CAPS_PERCENTAGE );
     713             :     }
     714           0 :     pFont->SetPhysFont( pOut );
     715             : 
     716           0 :     aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
     717           0 :     aPartSize.setHeight( pOut->GetTextHeight() );
     718           0 :     long nWidth = aPartSize.Width();
     719           0 :     if ( nKern )
     720             :     {
     721           0 :         aPos.X() += (nKern/2);
     722           0 :         if ( _nLen ) nWidth += (_nLen*long(nKern));
     723             :     }
     724           0 :     pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
     725             : 
     726             :     // Restore Font
     727           0 :     pFont->SetUnderline( eUnder );
     728           0 :     pFont->SetStrikeout( eStrike );
     729           0 :     if ( !bUpper )
     730           0 :         pFont->SetPropr( nProp );
     731           0 :     pFont->SetPhysFont( pOut );
     732             : 
     733           0 :     aPos.X() += nWidth-(nKern/2);
     734           0 : }
     735             : 
     736             : /*************************************************************************
     737             :  * SvxFont::DrawCapital() draws the uppercase letter.
     738             :  *************************************************************************/
     739             : 
     740           0 : void SvxFont::DrawCapital( OutputDevice *pOut,
     741             :                const Point &rPos, const OUString &rTxt,
     742             :                const sal_Int32 nIdx, const sal_Int32 nLen ) const
     743             : {
     744           0 :     SvxDoDrawCapital aDo( const_cast<SvxFont *>(this),pOut,rTxt,nIdx,nLen,rPos,nKern );
     745           0 :     DoOnCapitals( aDo );
     746           0 : }
     747             : 
     748             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11