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

Generated by: LCOV version 1.10