1cdf0e10cSrcweir /************************************************************************* 2cdf0e10cSrcweir * 3cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4cdf0e10cSrcweir * 5cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6cdf0e10cSrcweir * 7cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8cdf0e10cSrcweir * 9cdf0e10cSrcweir * This file is part of OpenOffice.org. 10cdf0e10cSrcweir * 11cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14cdf0e10cSrcweir * 15cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20cdf0e10cSrcweir * 21cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25cdf0e10cSrcweir * 26cdf0e10cSrcweir ************************************************************************/ 27cdf0e10cSrcweir 28cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29cdf0e10cSrcweir #include "precompiled_editeng.hxx" 30cdf0e10cSrcweir 31cdf0e10cSrcweir // include ---------------------------------------------------------------- 32cdf0e10cSrcweir 33cdf0e10cSrcweir #include <vcl/outdev.hxx> 34cdf0e10cSrcweir #include <vcl/print.hxx> 35cdf0e10cSrcweir #include <tools/poly.hxx> 36cdf0e10cSrcweir #include <unotools/charclass.hxx> 37cdf0e10cSrcweir #include <editeng/unolingu.hxx> 38cdf0e10cSrcweir #include <com/sun/star/i18n/KCharacterType.hpp> 39cdf0e10cSrcweir 40cdf0e10cSrcweir #define _SVX_SVXFONT_CXX 41cdf0e10cSrcweir 42cdf0e10cSrcweir #include <editeng/svxfont.hxx> 43cdf0e10cSrcweir #include <editeng/escpitem.hxx> 44cdf0e10cSrcweir 45cdf0e10cSrcweir // Minimum: Prozentwert fuers kernen 46cdf0e10cSrcweir #define MINKERNPERCENT 5 47cdf0e10cSrcweir 48*0f91224eSPedro Giffuni // prop. Size of the small cap letters 49*0f91224eSPedro Giffuni #define KAPITAELCHENPROP 75 50cdf0e10cSrcweir 51cdf0e10cSrcweir #ifndef REDUCEDSVXFONT 52cdf0e10cSrcweir const sal_Unicode CH_BLANK = sal_Unicode(' '); // ' ' Leerzeichen 53cdf0e10cSrcweir static sal_Char __READONLY_DATA sDoubleSpace[] = " "; 54cdf0e10cSrcweir #endif 55cdf0e10cSrcweir 56cdf0e10cSrcweir /************************************************************************* 57cdf0e10cSrcweir * class SvxFont 58cdf0e10cSrcweir *************************************************************************/ 59cdf0e10cSrcweir 60cdf0e10cSrcweir SvxFont::SvxFont() 61cdf0e10cSrcweir { 62cdf0e10cSrcweir nKern = nEsc = 0; 63cdf0e10cSrcweir nPropr = 100; 64cdf0e10cSrcweir eCaseMap = SVX_CASEMAP_NOT_MAPPED; 65cdf0e10cSrcweir eLang = LANGUAGE_SYSTEM; 66cdf0e10cSrcweir } 67cdf0e10cSrcweir 68cdf0e10cSrcweir SvxFont::SvxFont( const Font &rFont ) 69cdf0e10cSrcweir : Font( rFont ) 70cdf0e10cSrcweir { 71cdf0e10cSrcweir nKern = nEsc = 0; 72cdf0e10cSrcweir nPropr = 100; 73cdf0e10cSrcweir eCaseMap = SVX_CASEMAP_NOT_MAPPED; 74cdf0e10cSrcweir eLang = LANGUAGE_SYSTEM; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir 77cdf0e10cSrcweir /************************************************************************* 78cdf0e10cSrcweir * class SvxFont: Copy-Ctor 79cdf0e10cSrcweir *************************************************************************/ 80cdf0e10cSrcweir 81cdf0e10cSrcweir SvxFont::SvxFont( const SvxFont &rFont ) 82cdf0e10cSrcweir : Font( rFont ) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir nKern = rFont.GetFixKerning(); 85cdf0e10cSrcweir nEsc = rFont.GetEscapement(); 86cdf0e10cSrcweir nPropr = rFont.GetPropr(); 87cdf0e10cSrcweir eCaseMap = rFont.GetCaseMap(); 88cdf0e10cSrcweir eLang = rFont.GetLanguage(); 89cdf0e10cSrcweir } 90cdf0e10cSrcweir 91cdf0e10cSrcweir /************************************************************************* 92cdf0e10cSrcweir * static SvxFont::DrawArrow 93cdf0e10cSrcweir *************************************************************************/ 94cdf0e10cSrcweir 95cdf0e10cSrcweir void SvxFont::DrawArrow( OutputDevice &rOut, const Rectangle& rRect, 96cdf0e10cSrcweir const Size& rSize, const Color& rCol, sal_Bool bLeft ) 97cdf0e10cSrcweir { 98cdf0e10cSrcweir long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2; 99cdf0e10cSrcweir long nRight = nLeft + rSize.Width(); 100cdf0e10cSrcweir long nMid = ( rRect.Top() + rRect.Bottom() ) / 2; 101cdf0e10cSrcweir long nTop = nMid - rSize.Height() / 2; 102cdf0e10cSrcweir long nBottom = nTop + rSize.Height(); 103cdf0e10cSrcweir if( nLeft < rRect.Left() ) 104cdf0e10cSrcweir { 105cdf0e10cSrcweir nLeft = rRect.Left(); 106cdf0e10cSrcweir nRight = rRect.Right(); 107cdf0e10cSrcweir } 108cdf0e10cSrcweir if( nTop < rRect.Top() ) 109cdf0e10cSrcweir { 110cdf0e10cSrcweir nTop = rRect.Top(); 111cdf0e10cSrcweir nBottom = rRect.Bottom(); 112cdf0e10cSrcweir } 113cdf0e10cSrcweir Polygon aPoly; 114cdf0e10cSrcweir Point aTmp( bLeft ? nLeft : nRight, nMid ); 115cdf0e10cSrcweir Point aNxt( bLeft ? nRight : nLeft, nTop ); 116cdf0e10cSrcweir aPoly.Insert( 0, aTmp ); 117cdf0e10cSrcweir aPoly.Insert( 0, aNxt ); 118cdf0e10cSrcweir aNxt.Y() = nBottom; 119cdf0e10cSrcweir aPoly.Insert( 0, aNxt ); 120cdf0e10cSrcweir aPoly.Insert( 0, aTmp ); 121cdf0e10cSrcweir Color aOldLineColor = rOut.GetLineColor(); 122cdf0e10cSrcweir Color aOldFillColor = rOut.GetFillColor(); 123cdf0e10cSrcweir rOut.SetFillColor( rCol ); 124cdf0e10cSrcweir rOut.SetLineColor( Color( COL_BLACK ) ); 125cdf0e10cSrcweir rOut.DrawPolygon( aPoly ); 126cdf0e10cSrcweir rOut.DrawLine( aTmp, aNxt ); 127cdf0e10cSrcweir rOut.SetLineColor( aOldLineColor ); 128cdf0e10cSrcweir rOut.SetFillColor( aOldFillColor ); 129cdf0e10cSrcweir } 130cdf0e10cSrcweir 131cdf0e10cSrcweir /************************************************************************* 132cdf0e10cSrcweir * SvxFont::CalcCaseMap 133cdf0e10cSrcweir *************************************************************************/ 134cdf0e10cSrcweir 135cdf0e10cSrcweir XubString SvxFont::CalcCaseMap( const XubString &rTxt ) const 136cdf0e10cSrcweir { 137cdf0e10cSrcweir if( !IsCaseMap() || !rTxt.Len() ) return rTxt; 138cdf0e10cSrcweir XubString aTxt( rTxt ); 139cdf0e10cSrcweir // Ich muss mir noch die Sprache besorgen 140cdf0e10cSrcweir const LanguageType eLng = LANGUAGE_DONTKNOW == eLang 141cdf0e10cSrcweir ? LANGUAGE_SYSTEM : eLang; 142cdf0e10cSrcweir 143cdf0e10cSrcweir CharClass aCharClass( SvxCreateLocale( eLng ) ); 144cdf0e10cSrcweir 145cdf0e10cSrcweir switch( eCaseMap ) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir case SVX_CASEMAP_KAPITAELCHEN: 148cdf0e10cSrcweir case SVX_CASEMAP_VERSALIEN: 149cdf0e10cSrcweir { 150cdf0e10cSrcweir aCharClass.toUpper( aTxt ); 151cdf0e10cSrcweir break; 152cdf0e10cSrcweir } 153cdf0e10cSrcweir 154cdf0e10cSrcweir case SVX_CASEMAP_GEMEINE: 155cdf0e10cSrcweir { 156cdf0e10cSrcweir aCharClass.toLower( aTxt ); 157cdf0e10cSrcweir break; 158cdf0e10cSrcweir } 159cdf0e10cSrcweir case SVX_CASEMAP_TITEL: 160cdf0e10cSrcweir { 161cdf0e10cSrcweir // Jeder Wortbeginn wird gross geschrieben, 162cdf0e10cSrcweir // der Rest des Wortes wird unbesehen uebernommen. 163cdf0e10cSrcweir // Bug: wenn das Attribut mitten im Wort beginnt. 164cdf0e10cSrcweir sal_Bool bBlank = sal_True; 165cdf0e10cSrcweir 166cdf0e10cSrcweir for( sal_uInt16 i = 0; i < aTxt.Len(); ++i ) 167cdf0e10cSrcweir { 168cdf0e10cSrcweir if( sal_Unicode(' ') == aTxt.GetChar(i) || sal_Unicode('\t') == aTxt.GetChar(i) ) 169cdf0e10cSrcweir bBlank = sal_True; 170cdf0e10cSrcweir else 171cdf0e10cSrcweir { 172cdf0e10cSrcweir if( bBlank ) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir String aTemp( aTxt.GetChar( i ) ); 175cdf0e10cSrcweir aCharClass.toUpper( aTemp ); 176cdf0e10cSrcweir aTxt.Replace( i, 1, aTemp ); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir bBlank = sal_False; 179cdf0e10cSrcweir } 180cdf0e10cSrcweir } 181cdf0e10cSrcweir break; 182cdf0e10cSrcweir } 183cdf0e10cSrcweir default: 184cdf0e10cSrcweir { 185cdf0e10cSrcweir DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap"); 186cdf0e10cSrcweir break; 187cdf0e10cSrcweir } 188cdf0e10cSrcweir } 189cdf0e10cSrcweir return aTxt; 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir /************************************************************************* 193cdf0e10cSrcweir * Hier beginnen die Methoden, die im Writer nicht benutzt werden koennen, 194cdf0e10cSrcweir * deshalb kann man diesen Bereich durch setzen von REDUCEDSVXFONT ausklammern. 195cdf0e10cSrcweir *************************************************************************/ 196cdf0e10cSrcweir #ifndef REDUCEDSVXFONT 197cdf0e10cSrcweir 198cdf0e10cSrcweir /************************************************************************* 199cdf0e10cSrcweir * class SvxDoCapitals 200cdf0e10cSrcweir * die virtuelle Methode Do wird von SvxFont::DoOnCapitals abwechselnd mit 201cdf0e10cSrcweir * den "Gross-" und "Kleinbuchstaben"-Teilen aufgerufen. 202cdf0e10cSrcweir * Die Ableitungen von SvxDoCapitals erfuellen diese Methode mit Leben. 203cdf0e10cSrcweir *************************************************************************/ 204cdf0e10cSrcweir 205cdf0e10cSrcweir class SvxDoCapitals 206cdf0e10cSrcweir { 207cdf0e10cSrcweir protected: 208cdf0e10cSrcweir OutputDevice *pOut; 209cdf0e10cSrcweir const XubString &rTxt; 210cdf0e10cSrcweir const xub_StrLen nIdx; 211cdf0e10cSrcweir const xub_StrLen nLen; 212cdf0e10cSrcweir 213cdf0e10cSrcweir public: 214cdf0e10cSrcweir SvxDoCapitals( OutputDevice *_pOut, const XubString &_rTxt, 215cdf0e10cSrcweir const xub_StrLen _nIdx, const xub_StrLen _nLen ) 216cdf0e10cSrcweir : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen) 217cdf0e10cSrcweir { } 218cdf0e10cSrcweir 219cdf0e10cSrcweir virtual void DoSpace( const sal_Bool bDraw ); 220cdf0e10cSrcweir virtual void SetSpace(); 221cdf0e10cSrcweir virtual void Do( const XubString &rTxt, 222cdf0e10cSrcweir const xub_StrLen nIdx, const xub_StrLen nLen, 223cdf0e10cSrcweir const sal_Bool bUpper ) = 0; 224cdf0e10cSrcweir 225cdf0e10cSrcweir inline OutputDevice *GetOut() { return pOut; } 226cdf0e10cSrcweir inline const XubString &GetTxt() const { return rTxt; } 227cdf0e10cSrcweir xub_StrLen GetIdx() const { return nIdx; } 228cdf0e10cSrcweir xub_StrLen GetLen() const { return nLen; } 229cdf0e10cSrcweir }; 230cdf0e10cSrcweir 231cdf0e10cSrcweir void SvxDoCapitals::DoSpace( const sal_Bool /*bDraw*/ ) { } 232cdf0e10cSrcweir 233cdf0e10cSrcweir void SvxDoCapitals::SetSpace() { } 234cdf0e10cSrcweir 235cdf0e10cSrcweir void SvxDoCapitals::Do( const XubString &/*_rTxt*/, const xub_StrLen /*_nIdx*/, 236cdf0e10cSrcweir const xub_StrLen /*_nLen*/, const sal_Bool /*bUpper*/ ) { } 237cdf0e10cSrcweir 238cdf0e10cSrcweir /************************************************************************* 239cdf0e10cSrcweir * SvxFont::DoOnCapitals() const 240cdf0e10cSrcweir * zerlegt den String in Gross- und Kleinbuchstaben und ruft jeweils die 241cdf0e10cSrcweir * Methode SvxDoCapitals::Do( ) auf. 242cdf0e10cSrcweir *************************************************************************/ 243cdf0e10cSrcweir 244cdf0e10cSrcweir void SvxFont::DoOnCapitals(SvxDoCapitals &rDo, const xub_StrLen nPartLen) const 245cdf0e10cSrcweir { 246cdf0e10cSrcweir const XubString &rTxt = rDo.GetTxt(); 247cdf0e10cSrcweir const xub_StrLen nIdx = rDo.GetIdx(); 248cdf0e10cSrcweir const xub_StrLen nLen = STRING_LEN == nPartLen ? rDo.GetLen() : nPartLen; 249cdf0e10cSrcweir 250cdf0e10cSrcweir const XubString aTxt( CalcCaseMap( rTxt ) ); 251cdf0e10cSrcweir const sal_uInt16 nTxtLen = Min( rTxt.Len(), nLen ); 252cdf0e10cSrcweir sal_uInt16 nPos = 0; 253cdf0e10cSrcweir sal_uInt16 nOldPos = nPos; 254cdf0e10cSrcweir 255cdf0e10cSrcweir // #108210# 256cdf0e10cSrcweir // Test if string length differ between original and CaseMapped 257cdf0e10cSrcweir sal_Bool bCaseMapLengthDiffers(aTxt.Len() != rTxt.Len()); 258cdf0e10cSrcweir 259cdf0e10cSrcweir const LanguageType eLng = LANGUAGE_DONTKNOW == eLang 260cdf0e10cSrcweir ? LANGUAGE_SYSTEM : eLang; 261cdf0e10cSrcweir 262cdf0e10cSrcweir CharClass aCharClass( SvxCreateLocale( eLng ) ); 263cdf0e10cSrcweir String aCharString; 264cdf0e10cSrcweir 265cdf0e10cSrcweir while( nPos < nTxtLen ) 266cdf0e10cSrcweir { 267cdf0e10cSrcweir // Erst kommen die Upper-Chars dran 268cdf0e10cSrcweir 269cdf0e10cSrcweir // 4251: Es gibt Zeichen, die Upper _und_ Lower sind (z.B. das Blank). 270cdf0e10cSrcweir // Solche Zweideutigkeiten fuehren ins Chaos, deswegen werden diese 271cdf0e10cSrcweir // Zeichen der Menge Lower zugeordnet ! 272cdf0e10cSrcweir 273cdf0e10cSrcweir while( nPos < nTxtLen ) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir aCharString = rTxt.GetChar( nPos + nIdx ); 276cdf0e10cSrcweir sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 ); 277cdf0e10cSrcweir if ( nCharacterType & ::com::sun::star::i18n::KCharacterType::LOWER ) 278cdf0e10cSrcweir break; 279cdf0e10cSrcweir if ( ! ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) ) 280cdf0e10cSrcweir break; 281cdf0e10cSrcweir ++nPos; 282cdf0e10cSrcweir } 283cdf0e10cSrcweir if( nOldPos != nPos ) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir if(bCaseMapLengthDiffers) 286cdf0e10cSrcweir { 287cdf0e10cSrcweir // #108210# 288cdf0e10cSrcweir // If strings differ work preparing the necessary snippet to address that 289cdf0e10cSrcweir // potential difference 290cdf0e10cSrcweir const XubString aSnippet(rTxt, nIdx + nOldPos, nPos-nOldPos); 291cdf0e10cSrcweir XubString aNewText = CalcCaseMap(aSnippet); 292cdf0e10cSrcweir 293cdf0e10cSrcweir rDo.Do( aNewText, 0, aNewText.Len(), sal_True ); 294cdf0e10cSrcweir } 295cdf0e10cSrcweir else 296cdf0e10cSrcweir { 297cdf0e10cSrcweir rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_True ); 298cdf0e10cSrcweir } 299cdf0e10cSrcweir 300cdf0e10cSrcweir nOldPos = nPos; 301cdf0e10cSrcweir } 302cdf0e10cSrcweir // Nun werden die Lower-Chars verarbeitet (ohne Blanks) 303cdf0e10cSrcweir while( nPos < nTxtLen ) 304cdf0e10cSrcweir { 305cdf0e10cSrcweir sal_uInt32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 ); 306cdf0e10cSrcweir if ( ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) ) 307cdf0e10cSrcweir break; 308cdf0e10cSrcweir if ( CH_BLANK == aCharString ) 309cdf0e10cSrcweir break; 310cdf0e10cSrcweir if( ++nPos < nTxtLen ) 311cdf0e10cSrcweir aCharString = rTxt.GetChar( nPos + nIdx ); 312cdf0e10cSrcweir } 313cdf0e10cSrcweir if( nOldPos != nPos ) 314cdf0e10cSrcweir { 315cdf0e10cSrcweir if(bCaseMapLengthDiffers) 316cdf0e10cSrcweir { 317cdf0e10cSrcweir // #108210# 318cdf0e10cSrcweir // If strings differ work preparing the necessary snippet to address that 319cdf0e10cSrcweir // potential difference 320cdf0e10cSrcweir const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos); 321cdf0e10cSrcweir XubString aNewText = CalcCaseMap(aSnippet); 322cdf0e10cSrcweir 323cdf0e10cSrcweir rDo.Do( aNewText, 0, aNewText.Len(), sal_False ); 324cdf0e10cSrcweir } 325cdf0e10cSrcweir else 326cdf0e10cSrcweir { 327cdf0e10cSrcweir rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_False ); 328cdf0e10cSrcweir } 329cdf0e10cSrcweir 330cdf0e10cSrcweir nOldPos = nPos; 331cdf0e10cSrcweir } 332cdf0e10cSrcweir // Nun werden die Blanks verarbeitet 333cdf0e10cSrcweir while( nPos < nTxtLen && CH_BLANK == aCharString && ++nPos < nTxtLen ) 334cdf0e10cSrcweir aCharString = rTxt.GetChar( nPos + nIdx ); 335cdf0e10cSrcweir 336cdf0e10cSrcweir if( nOldPos != nPos ) 337cdf0e10cSrcweir { 338cdf0e10cSrcweir rDo.DoSpace( sal_False ); 339cdf0e10cSrcweir 340cdf0e10cSrcweir if(bCaseMapLengthDiffers) 341cdf0e10cSrcweir { 342cdf0e10cSrcweir // #108210# 343cdf0e10cSrcweir // If strings differ work preparing the necessary snippet to address that 344cdf0e10cSrcweir // potential difference 345cdf0e10cSrcweir const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos); 346cdf0e10cSrcweir XubString aNewText = CalcCaseMap(aSnippet); 347cdf0e10cSrcweir 348cdf0e10cSrcweir rDo.Do( aNewText, 0, aNewText.Len(), sal_False ); 349cdf0e10cSrcweir } 350cdf0e10cSrcweir else 351cdf0e10cSrcweir { 352cdf0e10cSrcweir rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, sal_False ); 353cdf0e10cSrcweir } 354cdf0e10cSrcweir 355cdf0e10cSrcweir nOldPos = nPos; 356cdf0e10cSrcweir rDo.SetSpace(); 357cdf0e10cSrcweir } 358cdf0e10cSrcweir } 359cdf0e10cSrcweir rDo.DoSpace( sal_True ); 360cdf0e10cSrcweir } 361cdf0e10cSrcweir 362cdf0e10cSrcweir /************************************************************************** 363cdf0e10cSrcweir * SvxFont::SetPhysFont() 364cdf0e10cSrcweir *************************************************************************/ 365cdf0e10cSrcweir 366cdf0e10cSrcweir void SvxFont::SetPhysFont( OutputDevice *pOut ) const 367cdf0e10cSrcweir { 368cdf0e10cSrcweir const Font& rCurrentFont = pOut->GetFont(); 369cdf0e10cSrcweir if ( nPropr == 100 ) 370cdf0e10cSrcweir { 371cdf0e10cSrcweir if ( !rCurrentFont.IsSameInstance( *this ) ) 372cdf0e10cSrcweir pOut->SetFont( *this ); 373cdf0e10cSrcweir } 374cdf0e10cSrcweir else 375cdf0e10cSrcweir { 376cdf0e10cSrcweir Font aNewFont( *this ); 377cdf0e10cSrcweir Size aSize( aNewFont.GetSize() ); 378cdf0e10cSrcweir aNewFont.SetSize( Size( aSize.Width() * nPropr / 100L, 379cdf0e10cSrcweir aSize.Height() * nPropr / 100L ) ); 380cdf0e10cSrcweir if ( !rCurrentFont.IsSameInstance( aNewFont ) ) 381cdf0e10cSrcweir pOut->SetFont( aNewFont ); 382cdf0e10cSrcweir } 383cdf0e10cSrcweir } 384cdf0e10cSrcweir 385cdf0e10cSrcweir /************************************************************************* 386cdf0e10cSrcweir * SvxFont::ChgPhysFont() 387cdf0e10cSrcweir *************************************************************************/ 388cdf0e10cSrcweir 389cdf0e10cSrcweir Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const 390cdf0e10cSrcweir { 391cdf0e10cSrcweir Font aOldFont( pOut->GetFont() ); 392cdf0e10cSrcweir SetPhysFont( pOut ); 393cdf0e10cSrcweir return aOldFont; 394cdf0e10cSrcweir } 395cdf0e10cSrcweir 396cdf0e10cSrcweir /************************************************************************* 397cdf0e10cSrcweir * SvxFont::GetPhysTxtSize() 398cdf0e10cSrcweir *************************************************************************/ 399cdf0e10cSrcweir 400cdf0e10cSrcweir Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt, 401cdf0e10cSrcweir const xub_StrLen nIdx, const xub_StrLen nLen ) const 402cdf0e10cSrcweir { 403cdf0e10cSrcweir if ( !IsCaseMap() && !IsKern() ) 404cdf0e10cSrcweir return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ), 405cdf0e10cSrcweir pOut->GetTextHeight() ); 406cdf0e10cSrcweir 407cdf0e10cSrcweir Size aTxtSize; 408cdf0e10cSrcweir aTxtSize.setHeight( pOut->GetTextHeight() ); 409cdf0e10cSrcweir if ( !IsCaseMap() ) 410cdf0e10cSrcweir aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) ); 411cdf0e10cSrcweir else 412cdf0e10cSrcweir { 413cdf0e10cSrcweir // #108210# 414cdf0e10cSrcweir const XubString aNewText = CalcCaseMap(rTxt); 415cdf0e10cSrcweir sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len()); 416cdf0e10cSrcweir sal_Int32 nWidth(0L); 417cdf0e10cSrcweir 418cdf0e10cSrcweir if(bCaseMapLengthDiffers) 419cdf0e10cSrcweir { 420cdf0e10cSrcweir // If strings differ work preparing the necessary snippet to address that 421cdf0e10cSrcweir // potential difference 422cdf0e10cSrcweir const XubString aSnippet(rTxt, nIdx, nLen); 423cdf0e10cSrcweir XubString _aNewText = CalcCaseMap(aSnippet); 424cdf0e10cSrcweir nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.Len() ); 425cdf0e10cSrcweir } 426cdf0e10cSrcweir else 427cdf0e10cSrcweir { 428cdf0e10cSrcweir nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen ); 429cdf0e10cSrcweir } 430cdf0e10cSrcweir 431cdf0e10cSrcweir aTxtSize.setWidth(nWidth); 432cdf0e10cSrcweir } 433cdf0e10cSrcweir 434cdf0e10cSrcweir if( IsKern() && ( nLen > 1 ) ) 435cdf0e10cSrcweir aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) ); 436cdf0e10cSrcweir 437cdf0e10cSrcweir return aTxtSize; 438cdf0e10cSrcweir } 439cdf0e10cSrcweir 440cdf0e10cSrcweir Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt ) 441cdf0e10cSrcweir { 442cdf0e10cSrcweir if ( !IsCaseMap() && !IsKern() ) 443cdf0e10cSrcweir return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() ); 444cdf0e10cSrcweir 445cdf0e10cSrcweir Size aTxtSize; 446cdf0e10cSrcweir aTxtSize.setHeight( pOut->GetTextHeight() ); 447cdf0e10cSrcweir if ( !IsCaseMap() ) 448cdf0e10cSrcweir aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) ); 449cdf0e10cSrcweir else 450cdf0e10cSrcweir aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) ); 451cdf0e10cSrcweir 452cdf0e10cSrcweir if( IsKern() && ( rTxt.Len() > 1 ) ) 453cdf0e10cSrcweir aTxtSize.Width() += ( ( rTxt.Len()-1 ) * long( nKern ) ); 454cdf0e10cSrcweir 455cdf0e10cSrcweir return aTxtSize; 456cdf0e10cSrcweir } 457cdf0e10cSrcweir 458cdf0e10cSrcweir Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const XubString &rTxt, 459cdf0e10cSrcweir const sal_uInt16 nIdx, const sal_uInt16 nLen, sal_Int32* pDXArray ) const 460cdf0e10cSrcweir { 461cdf0e10cSrcweir if ( !IsCaseMap() && !IsKern() ) 462cdf0e10cSrcweir return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ), 463cdf0e10cSrcweir pOut->GetTextHeight() ); 464cdf0e10cSrcweir 465cdf0e10cSrcweir Size aTxtSize; 466cdf0e10cSrcweir aTxtSize.setHeight( pOut->GetTextHeight() ); 467cdf0e10cSrcweir if ( !IsCaseMap() ) 468cdf0e10cSrcweir aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) ); 469cdf0e10cSrcweir else 470cdf0e10cSrcweir aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ), 471cdf0e10cSrcweir pDXArray, nIdx, nLen ) ); 472cdf0e10cSrcweir 473cdf0e10cSrcweir if( IsKern() && ( nLen > 1 ) ) 474cdf0e10cSrcweir { 475cdf0e10cSrcweir aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) ); 476cdf0e10cSrcweir 477cdf0e10cSrcweir if ( pDXArray ) 478cdf0e10cSrcweir { 479cdf0e10cSrcweir for ( xub_StrLen i = 0; i < nLen; i++ ) 480cdf0e10cSrcweir pDXArray[i] += ( (i+1) * long( nKern ) ); 481cdf0e10cSrcweir // Der letzte ist um ein nKern zu gross: 482cdf0e10cSrcweir pDXArray[nLen-1] -= nKern; 483cdf0e10cSrcweir } 484cdf0e10cSrcweir } 485cdf0e10cSrcweir return aTxtSize; 486cdf0e10cSrcweir } 487cdf0e10cSrcweir 488cdf0e10cSrcweir /************************************************************************* 489cdf0e10cSrcweir * SvxFont::GetTxtSize() 490cdf0e10cSrcweir *************************************************************************/ 491cdf0e10cSrcweir 492cdf0e10cSrcweir Size SvxFont::GetTxtSize( const OutputDevice *pOut, const XubString &rTxt, 493cdf0e10cSrcweir const xub_StrLen nIdx, const xub_StrLen nLen ) 494cdf0e10cSrcweir { 495cdf0e10cSrcweir xub_StrLen nTmp = nLen; 496cdf0e10cSrcweir if ( nTmp == STRING_LEN ) // schon initialisiert? 497cdf0e10cSrcweir nTmp = rTxt.Len(); 498cdf0e10cSrcweir Font aOldFont( ChgPhysFont((OutputDevice *)pOut) ); 499cdf0e10cSrcweir Size aTxtSize; 500cdf0e10cSrcweir if( IsCapital() && rTxt.Len() ) 501cdf0e10cSrcweir { 502cdf0e10cSrcweir aTxtSize = GetCapitalSize( pOut, rTxt, nIdx, nTmp ); 503cdf0e10cSrcweir } 504cdf0e10cSrcweir else aTxtSize = GetPhysTxtSize(pOut,rTxt,nIdx,nTmp); 505cdf0e10cSrcweir ((OutputDevice *)pOut)->SetFont( aOldFont ); 506cdf0e10cSrcweir return aTxtSize; 507cdf0e10cSrcweir } 508cdf0e10cSrcweir 509cdf0e10cSrcweir /************************************************************************* 510cdf0e10cSrcweir * SvxFont::DrawText() 511cdf0e10cSrcweir *************************************************************************/ 512cdf0e10cSrcweir 513cdf0e10cSrcweir void SvxFont::DrawText( OutputDevice *pOut, 514cdf0e10cSrcweir const Point &rPos, const XubString &rTxt, 515cdf0e10cSrcweir const xub_StrLen nIdx, const xub_StrLen nLen ) const 516cdf0e10cSrcweir { 517cdf0e10cSrcweir if( !nLen || !rTxt.Len() ) return; 518cdf0e10cSrcweir xub_StrLen nTmp = nLen; 519cdf0e10cSrcweir if ( nTmp == STRING_LEN ) // schon initialisiert? 520cdf0e10cSrcweir nTmp = rTxt.Len(); 521cdf0e10cSrcweir Point aPos( rPos ); 522cdf0e10cSrcweir if ( nEsc ) 523cdf0e10cSrcweir { 524cdf0e10cSrcweir Size aSize = (this->GetSize()); 525cdf0e10cSrcweir aPos.Y() -= ((nEsc*long(aSize.Height()))/ 100L); 526cdf0e10cSrcweir } 527cdf0e10cSrcweir Font aOldFont( ChgPhysFont( pOut ) ); 528cdf0e10cSrcweir 529cdf0e10cSrcweir if ( IsCapital() ) 530cdf0e10cSrcweir DrawCapital( pOut, aPos, rTxt, nIdx, nTmp ); 531cdf0e10cSrcweir else 532cdf0e10cSrcweir { 533cdf0e10cSrcweir Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nTmp ); 534cdf0e10cSrcweir 535cdf0e10cSrcweir if ( !IsCaseMap() ) 536cdf0e10cSrcweir pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp ); 537cdf0e10cSrcweir else 538cdf0e10cSrcweir pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), 539cdf0e10cSrcweir nIdx, nTmp ); 540cdf0e10cSrcweir } 541cdf0e10cSrcweir pOut->SetFont(aOldFont); 542cdf0e10cSrcweir } 543cdf0e10cSrcweir 544cdf0e10cSrcweir void SvxFont::QuickDrawText( OutputDevice *pOut, 545cdf0e10cSrcweir const Point &rPos, const XubString &rTxt, 546cdf0e10cSrcweir const xub_StrLen nIdx, const xub_StrLen nLen, const sal_Int32* pDXArray ) const 547cdf0e10cSrcweir { 548cdf0e10cSrcweir // Font muss ins OutputDevice selektiert sein... 549cdf0e10cSrcweir if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() ) 550cdf0e10cSrcweir { 551cdf0e10cSrcweir pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen ); 552cdf0e10cSrcweir return; 553cdf0e10cSrcweir } 554cdf0e10cSrcweir 555cdf0e10cSrcweir Point aPos( rPos ); 556cdf0e10cSrcweir 557cdf0e10cSrcweir if ( nEsc ) 558cdf0e10cSrcweir { 559cdf0e10cSrcweir long nDiff = GetSize().Height(); 560cdf0e10cSrcweir nDiff *= nEsc; 561cdf0e10cSrcweir nDiff /= 100; 562cdf0e10cSrcweir 563cdf0e10cSrcweir if ( !IsVertical() ) 564cdf0e10cSrcweir aPos.Y() -= nDiff; 565cdf0e10cSrcweir else 566cdf0e10cSrcweir aPos.X() += nDiff; 567cdf0e10cSrcweir } 568cdf0e10cSrcweir 569cdf0e10cSrcweir if( IsCapital() ) 570cdf0e10cSrcweir { 571cdf0e10cSrcweir DBG_ASSERT( !pDXArray, "DrawCapital nicht fuer TextArray!" ); 572cdf0e10cSrcweir DrawCapital( pOut, aPos, rTxt, nIdx, nLen ); 573cdf0e10cSrcweir } 574cdf0e10cSrcweir else 575cdf0e10cSrcweir { 576cdf0e10cSrcweir if ( IsKern() && !pDXArray ) 577cdf0e10cSrcweir { 578cdf0e10cSrcweir Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen ); 579cdf0e10cSrcweir 580cdf0e10cSrcweir if ( !IsCaseMap() ) 581cdf0e10cSrcweir pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen ); 582cdf0e10cSrcweir else 583cdf0e10cSrcweir pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen ); 584cdf0e10cSrcweir } 585cdf0e10cSrcweir else 586cdf0e10cSrcweir { 587cdf0e10cSrcweir if ( !IsCaseMap() ) 588cdf0e10cSrcweir pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen ); 589cdf0e10cSrcweir else 590cdf0e10cSrcweir pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen ); 591cdf0e10cSrcweir } 592cdf0e10cSrcweir } 593cdf0e10cSrcweir } 594cdf0e10cSrcweir 595cdf0e10cSrcweir // ----------------------------------------------------------------------- 596cdf0e10cSrcweir 597cdf0e10cSrcweir void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter, 598cdf0e10cSrcweir const Point &rPos, const XubString &rTxt, 599cdf0e10cSrcweir const xub_StrLen nIdx, const xub_StrLen nLen ) const 600cdf0e10cSrcweir { 601cdf0e10cSrcweir if ( !nLen || !rTxt.Len() ) 602cdf0e10cSrcweir return; 603cdf0e10cSrcweir xub_StrLen nTmp = nLen; 604cdf0e10cSrcweir 605cdf0e10cSrcweir if ( nTmp == STRING_LEN ) // schon initialisiert? 606cdf0e10cSrcweir nTmp = rTxt.Len(); 607cdf0e10cSrcweir Point aPos( rPos ); 608cdf0e10cSrcweir 609cdf0e10cSrcweir if ( nEsc ) 610cdf0e10cSrcweir { 611cdf0e10cSrcweir short nTmpEsc; 612cdf0e10cSrcweir if( DFLT_ESC_AUTO_SUPER == nEsc ) 613cdf0e10cSrcweir nTmpEsc = 33; 614cdf0e10cSrcweir else if( DFLT_ESC_AUTO_SUB == nEsc ) 615cdf0e10cSrcweir nTmpEsc = -20; 616cdf0e10cSrcweir else 617cdf0e10cSrcweir nTmpEsc = nEsc; 618cdf0e10cSrcweir Size aSize = ( this->GetSize() ); 619cdf0e10cSrcweir aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L ); 620cdf0e10cSrcweir } 621cdf0e10cSrcweir Font aOldFont( ChgPhysFont( pOut ) ); 622cdf0e10cSrcweir Font aOldPrnFont( ChgPhysFont( pPrinter ) ); 623cdf0e10cSrcweir 624cdf0e10cSrcweir if ( IsCapital() ) 625cdf0e10cSrcweir DrawCapital( pOut, aPos, rTxt, nIdx, nTmp ); 626cdf0e10cSrcweir else 627cdf0e10cSrcweir { 628cdf0e10cSrcweir Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp ); 629cdf0e10cSrcweir 630cdf0e10cSrcweir if ( !IsCaseMap() ) 631cdf0e10cSrcweir pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp ); 632cdf0e10cSrcweir else 633cdf0e10cSrcweir { 634cdf0e10cSrcweir // #108210# 635cdf0e10cSrcweir const XubString aNewText = CalcCaseMap(rTxt); 636cdf0e10cSrcweir sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len()); 637cdf0e10cSrcweir 638cdf0e10cSrcweir if(bCaseMapLengthDiffers) 639cdf0e10cSrcweir { 640cdf0e10cSrcweir // If strings differ work preparing the necessary snippet to address that 641cdf0e10cSrcweir // potential difference 642cdf0e10cSrcweir const XubString aSnippet(rTxt, nIdx, nTmp); 643cdf0e10cSrcweir XubString _aNewText = CalcCaseMap(aSnippet); 644cdf0e10cSrcweir 645cdf0e10cSrcweir pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.Len() ); 646cdf0e10cSrcweir } 647cdf0e10cSrcweir else 648cdf0e10cSrcweir { 649cdf0e10cSrcweir pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp ); 650cdf0e10cSrcweir } 651cdf0e10cSrcweir } 652cdf0e10cSrcweir } 653cdf0e10cSrcweir pOut->SetFont(aOldFont); 654cdf0e10cSrcweir pPrinter->SetFont( aOldPrnFont ); 655cdf0e10cSrcweir } 656cdf0e10cSrcweir 657cdf0e10cSrcweir // ----------------------------------------------------------------------- 658cdf0e10cSrcweir 659cdf0e10cSrcweir SvxFont& SvxFont::operator=( const Font& rFont ) 660cdf0e10cSrcweir { 661cdf0e10cSrcweir Font::operator=( rFont ); 662cdf0e10cSrcweir return *this; 663cdf0e10cSrcweir } 664cdf0e10cSrcweir 665cdf0e10cSrcweir SvxFont& SvxFont::operator=( const SvxFont& rFont ) 666cdf0e10cSrcweir { 667cdf0e10cSrcweir Font::operator=( rFont ); 668cdf0e10cSrcweir eLang = rFont.eLang; 669cdf0e10cSrcweir eCaseMap = rFont.eCaseMap; 670cdf0e10cSrcweir nEsc = rFont.nEsc; 671cdf0e10cSrcweir nPropr = rFont.nPropr; 672cdf0e10cSrcweir nKern = rFont.nKern; 673cdf0e10cSrcweir return *this; 674cdf0e10cSrcweir } 675cdf0e10cSrcweir 676cdf0e10cSrcweir 677cdf0e10cSrcweir /************************************************************************* 678cdf0e10cSrcweir * class SvxDoGetCapitalSize 679cdf0e10cSrcweir * wird von SvxFont::GetCapitalSize() zur Berechnung der TxtSize bei 680cdf0e10cSrcweir * eingestellten Kapitaelchen benutzt. 681cdf0e10cSrcweir *************************************************************************/ 682cdf0e10cSrcweir 683cdf0e10cSrcweir class SvxDoGetCapitalSize : public SvxDoCapitals 684cdf0e10cSrcweir { 685cdf0e10cSrcweir protected: 686cdf0e10cSrcweir SvxFont* pFont; 687cdf0e10cSrcweir Size aTxtSize; 688cdf0e10cSrcweir short nKern; 689cdf0e10cSrcweir public: 690cdf0e10cSrcweir SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut, 691cdf0e10cSrcweir const XubString &_rTxt, const xub_StrLen _nIdx, 692cdf0e10cSrcweir const xub_StrLen _nLen, const short _nKrn ) 693cdf0e10cSrcweir : SvxDoCapitals( (OutputDevice*)_pOut, _rTxt, _nIdx, _nLen ), 694cdf0e10cSrcweir pFont( _pFnt ), 695cdf0e10cSrcweir nKern( _nKrn ) 696cdf0e10cSrcweir { } 697cdf0e10cSrcweir 698cdf0e10cSrcweir virtual void Do( const XubString &rTxt, const xub_StrLen nIdx, 699cdf0e10cSrcweir const xub_StrLen nLen, const sal_Bool bUpper ); 700cdf0e10cSrcweir 701cdf0e10cSrcweir inline const Size &GetSize() const { return aTxtSize; }; 702cdf0e10cSrcweir }; 703cdf0e10cSrcweir 704cdf0e10cSrcweir void SvxDoGetCapitalSize::Do( const XubString &_rTxt, const xub_StrLen _nIdx, 705cdf0e10cSrcweir const xub_StrLen _nLen, const sal_Bool bUpper ) 706cdf0e10cSrcweir { 707cdf0e10cSrcweir Size aPartSize; 708cdf0e10cSrcweir if ( !bUpper ) 709cdf0e10cSrcweir { 710cdf0e10cSrcweir sal_uInt8 nProp = pFont->GetPropr(); 711cdf0e10cSrcweir pFont->SetProprRel( KAPITAELCHENPROP ); 712cdf0e10cSrcweir pFont->SetPhysFont( pOut ); 713cdf0e10cSrcweir aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); 714cdf0e10cSrcweir aPartSize.setHeight( pOut->GetTextHeight() ); 715cdf0e10cSrcweir aTxtSize.Height() = aPartSize.Height(); 716cdf0e10cSrcweir pFont->SetPropr( nProp ); 717cdf0e10cSrcweir pFont->SetPhysFont( pOut ); 718cdf0e10cSrcweir } 719cdf0e10cSrcweir else 720cdf0e10cSrcweir { 721cdf0e10cSrcweir aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); 722cdf0e10cSrcweir aPartSize.setHeight( pOut->GetTextHeight() ); 723cdf0e10cSrcweir } 724cdf0e10cSrcweir aTxtSize.Width() += aPartSize.Width(); 725cdf0e10cSrcweir aTxtSize.Width() += ( _nLen * long( nKern ) ); 726cdf0e10cSrcweir } 727cdf0e10cSrcweir 728cdf0e10cSrcweir /************************************************************************* 729cdf0e10cSrcweir * SvxFont::GetCapitalSize() 730cdf0e10cSrcweir * berechnet TxtSize, wenn Kapitaelchen eingestellt sind. 731cdf0e10cSrcweir *************************************************************************/ 732cdf0e10cSrcweir 733cdf0e10cSrcweir Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const XubString &rTxt, 734cdf0e10cSrcweir const xub_StrLen nIdx, const xub_StrLen nLen) const 735cdf0e10cSrcweir { 736cdf0e10cSrcweir // Start: 737cdf0e10cSrcweir SvxDoGetCapitalSize aDo( (SvxFont *)this, pOut, rTxt, nIdx, nLen, nKern ); 738cdf0e10cSrcweir DoOnCapitals( aDo ); 739cdf0e10cSrcweir Size aTxtSize( aDo.GetSize() ); 740cdf0e10cSrcweir 741cdf0e10cSrcweir // End: 742cdf0e10cSrcweir if( !aTxtSize.Height() ) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir aTxtSize.setWidth( 0 ); 745cdf0e10cSrcweir aTxtSize.setHeight( pOut->GetTextHeight() ); 746cdf0e10cSrcweir } 747cdf0e10cSrcweir return aTxtSize; 748cdf0e10cSrcweir } 749cdf0e10cSrcweir 750cdf0e10cSrcweir /************************************************************************* 751cdf0e10cSrcweir * class SvxDoDrawCapital 752cdf0e10cSrcweir * wird von SvxFont::DrawCapital zur Ausgabe von Kapitaelchen benutzt. 753cdf0e10cSrcweir *************************************************************************/ 754cdf0e10cSrcweir 755cdf0e10cSrcweir class SvxDoDrawCapital : public SvxDoCapitals 756cdf0e10cSrcweir { 757cdf0e10cSrcweir protected: 758cdf0e10cSrcweir SvxFont *pFont; 759cdf0e10cSrcweir Point aPos; 760cdf0e10cSrcweir Point aSpacePos; 761cdf0e10cSrcweir short nKern; 762cdf0e10cSrcweir public: 763cdf0e10cSrcweir SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const XubString &_rTxt, 764cdf0e10cSrcweir const xub_StrLen _nIdx, const xub_StrLen _nLen, 765cdf0e10cSrcweir const Point &rPos, const short nKrn ) 766cdf0e10cSrcweir : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ), 767cdf0e10cSrcweir pFont( pFnt ), 768cdf0e10cSrcweir aPos( rPos ), 769cdf0e10cSrcweir aSpacePos( rPos ), 770cdf0e10cSrcweir nKern( nKrn ) 771cdf0e10cSrcweir { } 772cdf0e10cSrcweir virtual void DoSpace( const sal_Bool bDraw ); 773cdf0e10cSrcweir virtual void SetSpace(); 774cdf0e10cSrcweir virtual void Do( const XubString &rTxt, const xub_StrLen nIdx, 775cdf0e10cSrcweir const xub_StrLen nLen, const sal_Bool bUpper ); 776cdf0e10cSrcweir }; 777cdf0e10cSrcweir 778cdf0e10cSrcweir void SvxDoDrawCapital::DoSpace( const sal_Bool bDraw ) 779cdf0e10cSrcweir { 780cdf0e10cSrcweir if ( bDraw || pFont->IsWordLineMode() ) 781cdf0e10cSrcweir { 782cdf0e10cSrcweir sal_uInt16 nDiff = (sal_uInt16)(aPos.X() - aSpacePos.X()); 783cdf0e10cSrcweir if ( nDiff ) 784cdf0e10cSrcweir { 785cdf0e10cSrcweir sal_Bool bWordWise = pFont->IsWordLineMode(); 786cdf0e10cSrcweir sal_Bool bTrans = pFont->IsTransparent(); 787cdf0e10cSrcweir pFont->SetWordLineMode( sal_False ); 788cdf0e10cSrcweir pFont->SetTransparent( sal_True ); 789cdf0e10cSrcweir pFont->SetPhysFont( pOut ); 790cdf0e10cSrcweir pOut->DrawStretchText( aSpacePos, nDiff, XubString( sDoubleSpace, 791cdf0e10cSrcweir RTL_TEXTENCODING_MS_1252 ), 0, 2 ); 792cdf0e10cSrcweir pFont->SetWordLineMode( bWordWise ); 793cdf0e10cSrcweir pFont->SetTransparent( bTrans ); 794cdf0e10cSrcweir pFont->SetPhysFont( pOut ); 795cdf0e10cSrcweir } 796cdf0e10cSrcweir } 797cdf0e10cSrcweir } 798cdf0e10cSrcweir 799cdf0e10cSrcweir void SvxDoDrawCapital::SetSpace() 800cdf0e10cSrcweir { 801cdf0e10cSrcweir if ( pFont->IsWordLineMode() ) 802cdf0e10cSrcweir aSpacePos.X() = aPos.X(); 803cdf0e10cSrcweir } 804cdf0e10cSrcweir 805cdf0e10cSrcweir void SvxDoDrawCapital::Do( const XubString &_rTxt, const xub_StrLen _nIdx, 806cdf0e10cSrcweir const xub_StrLen _nLen, const sal_Bool bUpper) 807cdf0e10cSrcweir { 808cdf0e10cSrcweir sal_uInt8 nProp = 0; 809cdf0e10cSrcweir Size aPartSize; 810cdf0e10cSrcweir 811cdf0e10cSrcweir // Einstellen der gewuenschten Fonts 812cdf0e10cSrcweir FontUnderline eUnder = pFont->GetUnderline(); 813cdf0e10cSrcweir FontStrikeout eStrike = pFont->GetStrikeout(); 814cdf0e10cSrcweir pFont->SetUnderline( UNDERLINE_NONE ); 815cdf0e10cSrcweir pFont->SetStrikeout( STRIKEOUT_NONE ); 816cdf0e10cSrcweir if ( !bUpper ) 817cdf0e10cSrcweir { 818cdf0e10cSrcweir nProp = pFont->GetPropr(); 819cdf0e10cSrcweir pFont->SetProprRel( KAPITAELCHENPROP ); 820cdf0e10cSrcweir } 821cdf0e10cSrcweir pFont->SetPhysFont( pOut ); 822cdf0e10cSrcweir 823cdf0e10cSrcweir aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); 824cdf0e10cSrcweir aPartSize.setHeight( pOut->GetTextHeight() ); 825cdf0e10cSrcweir long nWidth = aPartSize.Width(); 826cdf0e10cSrcweir if ( nKern ) 827cdf0e10cSrcweir { 828cdf0e10cSrcweir aPos.X() += (nKern/2); 829cdf0e10cSrcweir if ( _nLen ) nWidth += (_nLen*long(nKern)); 830cdf0e10cSrcweir } 831cdf0e10cSrcweir pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen); 832cdf0e10cSrcweir 833cdf0e10cSrcweir // Font restaurieren 834cdf0e10cSrcweir pFont->SetUnderline( eUnder ); 835cdf0e10cSrcweir pFont->SetStrikeout( eStrike ); 836cdf0e10cSrcweir if ( !bUpper ) 837cdf0e10cSrcweir pFont->SetPropr( nProp ); 838cdf0e10cSrcweir pFont->SetPhysFont( pOut ); 839cdf0e10cSrcweir 840cdf0e10cSrcweir aPos.X() += nWidth-(nKern/2); 841cdf0e10cSrcweir } 842cdf0e10cSrcweir 843cdf0e10cSrcweir /************************************************************************* 844cdf0e10cSrcweir * SvxFont::DrawCapital() gibt Kapitaelchen aus. 845cdf0e10cSrcweir *************************************************************************/ 846cdf0e10cSrcweir 847cdf0e10cSrcweir void SvxFont::DrawCapital( OutputDevice *pOut, 848cdf0e10cSrcweir const Point &rPos, const XubString &rTxt, 849cdf0e10cSrcweir const xub_StrLen nIdx, const xub_StrLen nLen ) const 850cdf0e10cSrcweir { 851cdf0e10cSrcweir SvxDoDrawCapital aDo( (SvxFont *)this,pOut,rTxt,nIdx,nLen,rPos,nKern ); 852cdf0e10cSrcweir DoOnCapitals( aDo ); 853cdf0e10cSrcweir } 854cdf0e10cSrcweir 855cdf0e10cSrcweir #endif // !REDUCEDSVXFONT 856cdf0e10cSrcweir 857cdf0e10cSrcweir 858