LCOV - code coverage report
Current view: top level - editeng/source/items - svxfont.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 357 0.0 %
Date: 2014-04-14 Functions: 0 37 0.0 %
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           0 : SvxFont::SvxFont()
      35             : {
      36           0 :     nKern = nEsc = 0;
      37           0 :     nPropr = 100;
      38           0 :     eCaseMap = SVX_CASEMAP_NOT_MAPPED;
      39           0 :     SetLanguage(LANGUAGE_SYSTEM);
      40           0 : }
      41             : 
      42           0 : SvxFont::SvxFont( const Font &rFont )
      43           0 :     : Font( rFont )
      44             : {
      45           0 :     nKern = nEsc = 0;
      46           0 :     nPropr = 100;
      47           0 :     eCaseMap = SVX_CASEMAP_NOT_MAPPED;
      48           0 :     SetLanguage(LANGUAGE_SYSTEM);
      49           0 : }
      50             : 
      51           0 : SvxFont::SvxFont( const SvxFont &rFont )
      52           0 :     : Font( rFont )
      53             : {
      54           0 :     nKern = rFont.GetFixKerning();
      55           0 :     nEsc  = rFont.GetEscapement();
      56           0 :     nPropr = rFont.GetPropr();
      57           0 :     eCaseMap = rFont.GetCaseMap();
      58           0 :     SetLanguage(rFont.GetLanguage());
      59           0 : }
      60             : 
      61           0 : void SvxFont::DrawArrow( OutputDevice &rOut, const Rectangle& rRect,
      62             :     const Size& rSize, const Color& rCol, bool bLeft )
      63             : {
      64           0 :     long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2;
      65           0 :     long nRight = nLeft + rSize.Width();
      66           0 :     long nMid = ( rRect.Top() + rRect.Bottom() ) / 2;
      67           0 :     long nTop = nMid - rSize.Height() / 2;
      68           0 :     long nBottom = nTop + rSize.Height();
      69           0 :     if( nLeft < rRect.Left() )
      70             :     {
      71           0 :         nLeft = rRect.Left();
      72           0 :         nRight = rRect.Right();
      73             :     }
      74           0 :     if( nTop < rRect.Top() )
      75             :     {
      76           0 :         nTop = rRect.Top();
      77           0 :         nBottom = rRect.Bottom();
      78             :     }
      79           0 :     Polygon aPoly;
      80           0 :     Point aTmp( bLeft ? nLeft : nRight, nMid );
      81           0 :     Point aNxt( bLeft ? nRight : nLeft, nTop );
      82           0 :     aPoly.Insert( 0, aTmp );
      83           0 :     aPoly.Insert( 0, aNxt );
      84           0 :     aNxt.Y() = nBottom;
      85           0 :     aPoly.Insert( 0, aNxt );
      86           0 :     aPoly.Insert( 0, aTmp );
      87           0 :     Color aOldLineColor = rOut.GetLineColor();
      88           0 :     Color aOldFillColor = rOut.GetFillColor();
      89           0 :     rOut.SetFillColor( rCol );
      90           0 :     rOut.SetLineColor( Color( COL_BLACK ) );
      91           0 :     rOut.DrawPolygon( aPoly );
      92           0 :     rOut.DrawLine( aTmp, aNxt );
      93           0 :     rOut.SetLineColor( aOldLineColor );
      94           0 :     rOut.SetFillColor( aOldFillColor );
      95           0 : }
      96             : 
      97             : 
      98           0 : OUString SvxFont::CalcCaseMap(const OUString &rTxt) const
      99             : {
     100           0 :     if (!IsCaseMap() || rTxt.isEmpty())
     101           0 :         return rTxt;
     102           0 :     OUString aTxt(rTxt);
     103             :     // I still have to get the language
     104           0 :     const LanguageType eLang = LANGUAGE_DONTKNOW == GetLanguage()
     105           0 :                              ? LANGUAGE_SYSTEM : GetLanguage();
     106             : 
     107           0 :     LanguageTag aLanguageTag(eLang);
     108           0 :     CharClass aCharClass( aLanguageTag );
     109             : 
     110           0 :     switch( eCaseMap )
     111             :     {
     112             :         case SVX_CASEMAP_KAPITAELCHEN:
     113             :         case SVX_CASEMAP_VERSALIEN:
     114             :         {
     115           0 :             aTxt = aCharClass.uppercase( aTxt );
     116           0 :             break;
     117             :         }
     118             : 
     119             :         case SVX_CASEMAP_GEMEINE:
     120             :         {
     121           0 :             aTxt = aCharClass.lowercase( aTxt );
     122           0 :             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           0 :             bool bBlank = true;
     130             : 
     131           0 :             for (sal_Int32 i = 0; i < aTxt.getLength(); ++i)
     132             :             {
     133           0 :                 if( aTxt[i] == ' ' || aTxt[i] == '\t')
     134           0 :                     bBlank = true;
     135             :                 else
     136             :                 {
     137           0 :                     if (bBlank)
     138             :                     {
     139           0 :                         OUString sTitle(aCharClass.uppercase(OUString(aTxt[i])));
     140           0 :                         aTxt = aTxt.replaceAt(i, 1, sTitle);
     141             :                     }
     142           0 :                     bBlank = false;
     143             :                 }
     144             :             }
     145           0 :             break;
     146             :         }
     147             :         default:
     148             :         {
     149             :             DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap");
     150           0 :             break;
     151             :         }
     152             :     }
     153           0 :     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             :     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 sal_Bool bDraw );
     180             :     virtual void SetSpace();
     181             :     virtual void Do( const OUString &rTxt,
     182             :                      const sal_Int32 nIdx, const sal_Int32 nLen,
     183             :                      const sal_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 sal_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 :     sal_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(), sal_True );
     251             :             }
     252             :             else
     253             :             {
     254           0 :                 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_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(), sal_False );
     281             :             }
     282             :             else
     283             :             {
     284           0 :                 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_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( sal_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(), sal_False );
     306             :             }
     307             :             else
     308             :             {
     309           0 :                 rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, sal_False );
     310             :             }
     311             : 
     312           0 :             nOldPos = nPos;
     313           0 :             rDo.SetSpace();
     314             :         }
     315             :     }
     316           0 :     rDo.DoSpace( sal_True );
     317           0 : }
     318             : 
     319             : 
     320           0 : void SvxFont::SetPhysFont( OutputDevice *pOut ) const
     321             : {
     322           0 :     const Font& rCurrentFont = pOut->GetFont();
     323           0 :     if ( nPropr == 100 )
     324             :     {
     325           0 :         if ( !rCurrentFont.IsSameInstance( *this ) )
     326           0 :             pOut->SetFont( *this );
     327             :     }
     328             :     else
     329             :     {
     330           0 :         Font aNewFont( *this );
     331           0 :         Size aSize( aNewFont.GetSize() );
     332           0 :         aNewFont.SetSize( Size( aSize.Width() * nPropr / 100L,
     333           0 :                                     aSize.Height() * nPropr / 100L ) );
     334           0 :         if ( !rCurrentFont.IsSameInstance( aNewFont ) )
     335           0 :             pOut->SetFont( aNewFont );
     336             :     }
     337           0 : }
     338             : 
     339             : 
     340           0 : Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const
     341             : {
     342           0 :     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 :         sal_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           0 : Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const OUString &rTxt )
     389             : {
     390           0 :     if ( !IsCaseMap() && !IsKern() )
     391           0 :         return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() );
     392             : 
     393           0 :     Size aTxtSize;
     394           0 :     aTxtSize.setHeight( pOut->GetTextHeight() );
     395           0 :     if ( !IsCaseMap() )
     396           0 :         aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) );
     397             :     else
     398           0 :         aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) );
     399             : 
     400           0 :     if( IsKern() && ( rTxt.getLength() > 1 ) )
     401           0 :         aTxtSize.Width() += ( ( rTxt.getLength()-1 ) * long( nKern ) );
     402             : 
     403           0 :     return aTxtSize;
     404             : }
     405             : 
     406           0 : Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt,
     407             :                          const sal_Int32 nIdx, const sal_Int32 nLen, sal_Int32* pDXArray ) const
     408             : {
     409           0 :     if ( !IsCaseMap() && !IsKern() )
     410             :         return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ),
     411           0 :                      pOut->GetTextHeight() );
     412             : 
     413           0 :     Size aTxtSize;
     414           0 :     aTxtSize.setHeight( pOut->GetTextHeight() );
     415           0 :     if ( !IsCaseMap() )
     416           0 :         aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
     417             :     else
     418             :         aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
     419           0 :                            pDXArray, nIdx, nLen ) );
     420             : 
     421           0 :     if( IsKern() && ( nLen > 1 ) )
     422             :     {
     423           0 :         aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
     424             : 
     425           0 :         if ( pDXArray )
     426             :         {
     427           0 :             for ( sal_Int32 i = 0; i < nLen; i++ )
     428           0 :                 pDXArray[i] += ( (i+1) * long( nKern ) );
     429             :             // The last one is a nKern too big:
     430           0 :             pDXArray[nLen-1] -= nKern;
     431             :         }
     432             :     }
     433           0 :     return aTxtSize;
     434             : }
     435             : 
     436             : 
     437           0 : Size SvxFont::GetTxtSize( 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((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 :     ((OutputDevice *)pOut)->SetFont( aOldFont );
     451           0 :     return aTxtSize;
     452             : }
     453             : 
     454             : 
     455           0 : void SvxFont::QuickDrawText( OutputDevice *pOut,
     456             :     const Point &rPos, const OUString &rTxt,
     457             :     const sal_Int32 nIdx, const sal_Int32 nLen, const sal_Int32* pDXArray ) const
     458             : {
     459             :     // Font has to be selected in OutputDevice...
     460           0 :     if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
     461             :     {
     462           0 :         pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen );
     463           0 :         return;
     464             :     }
     465             : 
     466           0 :     Point aPos( rPos );
     467             : 
     468           0 :     if ( nEsc )
     469             :     {
     470           0 :         long nDiff = GetSize().Height();
     471           0 :         nDiff *= nEsc;
     472           0 :         nDiff /= 100;
     473             : 
     474           0 :         if ( !IsVertical() )
     475           0 :             aPos.Y() -= nDiff;
     476             :         else
     477           0 :             aPos.X() += nDiff;
     478             :     }
     479             : 
     480           0 :     if( IsCapital() )
     481             :     {
     482             :         DBG_ASSERT( !pDXArray, "DrawCapital not for TextArray!" );
     483           0 :         DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
     484             :     }
     485             :     else
     486             :     {
     487           0 :         if ( IsKern() && !pDXArray )
     488             :         {
     489           0 :             Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
     490             : 
     491           0 :             if ( !IsCaseMap() )
     492           0 :                 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
     493             :             else
     494           0 :                 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
     495             :         }
     496             :         else
     497             :         {
     498           0 :             if ( !IsCaseMap() )
     499           0 :                 pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
     500             :             else
     501           0 :                 pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen );
     502             :         }
     503             :     }
     504             : }
     505             : 
     506             : 
     507           0 : void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter,
     508             :                         const Point &rPos, const OUString &rTxt,
     509             :                         const sal_Int32 nIdx, const sal_Int32 nLen ) const
     510             : {
     511           0 :     if ( !nLen || rTxt.isEmpty() )
     512           0 :         return;
     513           0 :     sal_Int32 nTmp = nLen;
     514             : 
     515           0 :     if ( nTmp == SAL_MAX_INT32 )   // already initialized?
     516           0 :         nTmp = rTxt.getLength();
     517           0 :     Point aPos( rPos );
     518             : 
     519           0 :     if ( nEsc )
     520             :     {
     521             :         short nTmpEsc;
     522           0 :         if( DFLT_ESC_AUTO_SUPER == nEsc )
     523           0 :             nTmpEsc = 33;
     524           0 :         else if( DFLT_ESC_AUTO_SUB == nEsc )
     525           0 :             nTmpEsc = -20;
     526             :         else
     527           0 :             nTmpEsc = nEsc;
     528           0 :         Size aSize = ( this->GetSize() );
     529           0 :         aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L );
     530             :     }
     531           0 :     Font aOldFont( ChgPhysFont( pOut ) );
     532           0 :     Font aOldPrnFont( ChgPhysFont( pPrinter ) );
     533             : 
     534           0 :     if ( IsCapital() )
     535           0 :         DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
     536             :     else
     537             :     {
     538           0 :         Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
     539             : 
     540           0 :         if ( !IsCaseMap() )
     541           0 :             pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
     542             :         else
     543             :         {
     544             :             // #108210#
     545           0 :             const OUString aNewText = CalcCaseMap(rTxt);
     546           0 :             sal_Bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength());
     547             : 
     548           0 :             if(bCaseMapLengthDiffers)
     549             :             {
     550             :                 // If strings differ work preparing the necessary snippet to address that
     551             :                 // potential difference
     552           0 :                 const OUString aSnippet(rTxt.copy( nIdx, nTmp));
     553           0 :                 OUString _aNewText = CalcCaseMap(aSnippet);
     554             : 
     555           0 :                 pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.getLength() );
     556             :             }
     557             :             else
     558             :             {
     559           0 :                 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp );
     560           0 :             }
     561             :         }
     562             :     }
     563           0 :     pOut->SetFont(aOldFont);
     564           0 :     pPrinter->SetFont( aOldPrnFont );
     565             : }
     566             : 
     567             : 
     568           0 : SvxFont& SvxFont::operator=( const Font& rFont )
     569             : {
     570           0 :     Font::operator=( rFont );
     571           0 :     return *this;
     572             : }
     573             : 
     574           0 : SvxFont& SvxFont::operator=( const SvxFont& rFont )
     575             : {
     576           0 :     Font::operator=( rFont );
     577           0 :     eCaseMap = rFont.eCaseMap;
     578           0 :     nEsc = rFont.nEsc;
     579           0 :     nPropr = rFont.nPropr;
     580           0 :     nKern = rFont.nKern;
     581           0 :     return *this;
     582             : }
     583             : 
     584             : class SvxDoGetCapitalSize : public SvxDoCapitals
     585             : {
     586             : protected:
     587             :     SvxFont*    pFont;
     588             :     Size        aTxtSize;
     589             :     short       nKern;
     590             : public:
     591           0 :       SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut,
     592             :                            const OUString &_rTxt, const sal_Int32 _nIdx,
     593             :                            const sal_Int32 _nLen, const short _nKrn )
     594             :             : SvxDoCapitals( (OutputDevice*)_pOut, _rTxt, _nIdx, _nLen ),
     595             :               pFont( _pFnt ),
     596           0 :               nKern( _nKrn )
     597           0 :             { }
     598             : 
     599           0 :     virtual ~SvxDoGetCapitalSize() {}
     600             : 
     601             :     virtual void Do( const OUString &rTxt, const sal_Int32 nIdx,
     602             :                      const sal_Int32 nLen, const sal_Bool bUpper ) SAL_OVERRIDE;
     603             : 
     604           0 :     const Size &GetSize() const { return aTxtSize; };
     605             : };
     606             : 
     607           0 : void SvxDoGetCapitalSize::Do( const OUString &_rTxt, const sal_Int32 _nIdx,
     608             :                               const sal_Int32 _nLen, const sal_Bool bUpper )
     609             : {
     610           0 :     Size aPartSize;
     611           0 :     if ( !bUpper )
     612             :     {
     613           0 :         sal_uInt8 nProp = pFont->GetPropr();
     614           0 :         pFont->SetProprRel( SMALL_CAPS_PERCENTAGE );
     615           0 :         pFont->SetPhysFont( pOut );
     616           0 :         aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
     617           0 :         aPartSize.setHeight( pOut->GetTextHeight() );
     618           0 :         aTxtSize.Height() = aPartSize.Height();
     619           0 :         pFont->SetPropr( nProp );
     620           0 :         pFont->SetPhysFont( pOut );
     621             :     }
     622             :     else
     623             :     {
     624           0 :         aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
     625           0 :         aPartSize.setHeight( pOut->GetTextHeight() );
     626             :     }
     627           0 :     aTxtSize.Width() += aPartSize.Width();
     628           0 :     aTxtSize.Width() += ( _nLen * long( nKern ) );
     629           0 : }
     630             : 
     631           0 : Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt,
     632             :                              const sal_Int32 nIdx, const sal_Int32 nLen) const
     633             : {
     634             :     // Start:
     635           0 :     SvxDoGetCapitalSize aDo( (SvxFont *)this, pOut, rTxt, nIdx, nLen, nKern );
     636           0 :     DoOnCapitals( aDo );
     637           0 :     Size aTxtSize( aDo.GetSize() );
     638             : 
     639             :     // End:
     640           0 :     if( !aTxtSize.Height() )
     641             :     {
     642           0 :         aTxtSize.setWidth( 0 );
     643           0 :         aTxtSize.setHeight( pOut->GetTextHeight() );
     644             :     }
     645           0 :     return aTxtSize;
     646             : }
     647             : 
     648           0 : class SvxDoDrawCapital : public SvxDoCapitals
     649             : {
     650             : protected:
     651             :     SvxFont *pFont;
     652             :     Point aPos;
     653             :     Point aSpacePos;
     654             :     short nKern;
     655             : public:
     656           0 :     SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const OUString &_rTxt,
     657             :                       const sal_Int32 _nIdx, const sal_Int32 _nLen,
     658             :                       const Point &rPos, const short nKrn )
     659             :         : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ),
     660             :           pFont( pFnt ),
     661             :           aPos( rPos ),
     662             :           aSpacePos( rPos ),
     663           0 :           nKern( nKrn )
     664           0 :         { }
     665             :     virtual void DoSpace( const sal_Bool bDraw ) SAL_OVERRIDE;
     666             :     virtual void SetSpace() SAL_OVERRIDE;
     667             :     virtual void Do( const OUString &rTxt, const sal_Int32 nIdx,
     668             :                      const sal_Int32 nLen, const sal_Bool bUpper ) SAL_OVERRIDE;
     669             : };
     670             : 
     671           0 : void SvxDoDrawCapital::DoSpace( const sal_Bool bDraw )
     672             : {
     673           0 :     if ( bDraw || pFont->IsWordLineMode() )
     674             :     {
     675           0 :         sal_uLong nDiff = (sal_uLong)(aPos.X() - aSpacePos.X());
     676           0 :         if ( nDiff )
     677             :         {
     678           0 :             sal_Bool bWordWise = pFont->IsWordLineMode();
     679           0 :             sal_Bool bTrans = pFont->IsTransparent();
     680           0 :             pFont->SetWordLineMode( false );
     681           0 :             pFont->SetTransparent( true );
     682           0 :             pFont->SetPhysFont( pOut );
     683           0 :             pOut->DrawStretchText( aSpacePos, nDiff, "  ", 0, 2 );
     684           0 :             pFont->SetWordLineMode( bWordWise );
     685           0 :             pFont->SetTransparent( bTrans );
     686           0 :             pFont->SetPhysFont( pOut );
     687             :         }
     688             :     }
     689           0 : }
     690             : 
     691           0 : void SvxDoDrawCapital::SetSpace()
     692             : {
     693           0 :     if ( pFont->IsWordLineMode() )
     694           0 :         aSpacePos.X() = aPos.X();
     695           0 : }
     696             : 
     697           0 : void SvxDoDrawCapital::Do( const OUString &_rTxt, const sal_Int32 _nIdx,
     698             :                            const sal_Int32 _nLen, const sal_Bool bUpper)
     699             : {
     700           0 :     sal_uInt8 nProp = 0;
     701           0 :     Size aPartSize;
     702             : 
     703             :     // Set the desired font
     704           0 :     FontUnderline eUnder = pFont->GetUnderline();
     705           0 :     FontStrikeout eStrike = pFont->GetStrikeout();
     706           0 :     pFont->SetUnderline( UNDERLINE_NONE );
     707           0 :     pFont->SetStrikeout( STRIKEOUT_NONE );
     708           0 :     if ( !bUpper )
     709             :     {
     710           0 :         nProp = pFont->GetPropr();
     711           0 :         pFont->SetProprRel( SMALL_CAPS_PERCENTAGE );
     712             :     }
     713           0 :     pFont->SetPhysFont( pOut );
     714             : 
     715           0 :     aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
     716           0 :     aPartSize.setHeight( pOut->GetTextHeight() );
     717           0 :     long nWidth = aPartSize.Width();
     718           0 :     if ( nKern )
     719             :     {
     720           0 :         aPos.X() += (nKern/2);
     721           0 :         if ( _nLen ) nWidth += (_nLen*long(nKern));
     722             :     }
     723           0 :     pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
     724             : 
     725             :     // Restore Font
     726           0 :     pFont->SetUnderline( eUnder );
     727           0 :     pFont->SetStrikeout( eStrike );
     728           0 :     if ( !bUpper )
     729           0 :         pFont->SetPropr( nProp );
     730           0 :     pFont->SetPhysFont( pOut );
     731             : 
     732           0 :     aPos.X() += nWidth-(nKern/2);
     733           0 : }
     734             : 
     735             : /*************************************************************************
     736             :  * SvxFont::DrawCapital() draws the uppercase letter.
     737             :  *************************************************************************/
     738             : 
     739           0 : void SvxFont::DrawCapital( OutputDevice *pOut,
     740             :                const Point &rPos, const OUString &rTxt,
     741             :                const sal_Int32 nIdx, const sal_Int32 nLen ) const
     742             : {
     743           0 :     SvxDoDrawCapital aDo( (SvxFont *)this,pOut,rTxt,nIdx,nLen,rPos,nKern );
     744           0 :     DoOnCapitals( aDo );
     745           0 : }
     746             : 
     747             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10