1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_toolkit.hxx" 30 31 32 #include <toolkit/awt/vclxfont.hxx> 33 #include <toolkit/helper/vclunohelper.hxx> 34 #include <toolkit/helper/macros.hxx> 35 #include <cppuhelper/typeprovider.hxx> 36 #include <rtl/memory.h> 37 #include <rtl/uuid.h> 38 #include <rtl/ustring.h> 39 40 #include <vcl/outdev.hxx> 41 42 // ---------------------------------------------------- 43 // class VCLXFont 44 // ---------------------------------------------------- 45 VCLXFont::VCLXFont() 46 { 47 mpFontMetric = NULL; 48 } 49 50 VCLXFont::~VCLXFont() 51 { 52 delete mpFontMetric; 53 } 54 55 void VCLXFont::Init( ::com::sun::star::awt::XDevice& rxDev, const Font& rFont ) 56 { 57 mxDevice = &rxDev; 58 59 delete mpFontMetric; 60 mpFontMetric = NULL; 61 62 maFont = rFont; 63 } 64 65 sal_Bool VCLXFont::ImplAssertValidFontMetric() 66 { 67 if ( !mpFontMetric && mxDevice.is() ) 68 { 69 OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); 70 if ( pOutDev ) 71 { 72 Font aOldFont = pOutDev->GetFont(); 73 pOutDev->SetFont( maFont ); 74 mpFontMetric = new FontMetric( pOutDev->GetFontMetric() ); 75 pOutDev->SetFont( aOldFont ); 76 } 77 } 78 return mpFontMetric ? sal_True : sal_False; 79 } 80 81 82 // ::com::sun::star::uno::XInterface 83 ::com::sun::star::uno::Any VCLXFont::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) 84 { 85 ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, 86 SAL_STATIC_CAST( ::com::sun::star::awt::XFont*, this ), 87 SAL_STATIC_CAST( ::com::sun::star::awt::XFont2*, this ), 88 SAL_STATIC_CAST( ::com::sun::star::lang::XUnoTunnel*, this ), 89 SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); 90 return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); 91 } 92 93 // ::com::sun::star::lang::XUnoTunnel 94 IMPL_XUNOTUNNEL( VCLXFont ) 95 96 // ::com::sun::star::lang::XTypeProvider 97 IMPL_XTYPEPROVIDER_START( VCLXFont ) 98 getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont2>* ) NULL ) 99 IMPL_XTYPEPROVIDER_END 100 101 102 ::com::sun::star::awt::FontDescriptor VCLXFont::getFontDescriptor( ) throw(::com::sun::star::uno::RuntimeException) 103 { 104 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 105 106 return VCLUnoHelper::CreateFontDescriptor( maFont ); 107 108 } 109 110 ::com::sun::star::awt::SimpleFontMetric VCLXFont::getFontMetric( ) throw(::com::sun::star::uno::RuntimeException) 111 { 112 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 113 114 ::com::sun::star::awt::SimpleFontMetric aFM; 115 if ( ImplAssertValidFontMetric() ) 116 aFM = VCLUnoHelper::CreateFontMetric( *mpFontMetric ); 117 return aFM; 118 } 119 120 sal_Int16 VCLXFont::getCharWidth( sal_Unicode c ) throw(::com::sun::star::uno::RuntimeException) 121 { 122 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 123 124 sal_Int16 nRet = -1; 125 OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); 126 if ( pOutDev ) 127 { 128 Font aOldFont = pOutDev->GetFont(); 129 pOutDev->SetFont( maFont ); 130 131 nRet = sal::static_int_cast< sal_Int16 >( 132 pOutDev->GetTextWidth( String(c) )); 133 134 pOutDev->SetFont( aOldFont ); 135 } 136 return nRet; 137 } 138 139 ::com::sun::star::uno::Sequence< sal_Int16 > VCLXFont::getCharWidths( sal_Unicode nFirst, sal_Unicode nLast ) throw(::com::sun::star::uno::RuntimeException) 140 { 141 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 142 143 ::com::sun::star::uno::Sequence<sal_Int16> aSeq; 144 OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); 145 if ( pOutDev ) 146 { 147 Font aOldFont = pOutDev->GetFont(); 148 pOutDev->SetFont( maFont ); 149 150 sal_Int16 nCount = nLast-nFirst + 1; 151 aSeq = ::com::sun::star::uno::Sequence<sal_Int16>( nCount ); 152 for ( sal_uInt16 n = 0; n < nCount; n++ ) 153 { 154 aSeq.getArray()[n] = sal::static_int_cast< sal_Int16 >( 155 pOutDev->GetTextWidth( 156 String(static_cast< sal_Unicode >(nFirst+n)) )); 157 } 158 159 pOutDev->SetFont( aOldFont ); 160 } 161 return aSeq; 162 } 163 164 sal_Int32 VCLXFont::getStringWidth( const ::rtl::OUString& str ) throw(::com::sun::star::uno::RuntimeException) 165 { 166 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 167 168 sal_Int32 nRet = -1; 169 OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); 170 if ( pOutDev ) 171 { 172 Font aOldFont = pOutDev->GetFont(); 173 pOutDev->SetFont( maFont ); 174 nRet = pOutDev->GetTextWidth( str ); 175 pOutDev->SetFont( aOldFont ); 176 } 177 return nRet; 178 } 179 180 sal_Int32 VCLXFont::getStringWidthArray( const ::rtl::OUString& str, ::com::sun::star::uno::Sequence< sal_Int32 >& rDXArray ) throw(::com::sun::star::uno::RuntimeException) 181 { 182 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 183 184 sal_Int32 nRet = -1; 185 OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); 186 if ( pOutDev ) 187 { 188 Font aOldFont = pOutDev->GetFont(); 189 pOutDev->SetFont( maFont ); 190 rDXArray = ::com::sun::star::uno::Sequence<sal_Int32>( str.getLength() ); 191 nRet = pOutDev->GetTextArray( str, rDXArray.getArray() ); 192 pOutDev->SetFont( aOldFont ); 193 } 194 return nRet; 195 } 196 197 void VCLXFont::getKernPairs( ::com::sun::star::uno::Sequence< sal_Unicode >& rnChars1, ::com::sun::star::uno::Sequence< sal_Unicode >& rnChars2, ::com::sun::star::uno::Sequence< sal_Int16 >& rnKerns ) throw(::com::sun::star::uno::RuntimeException) 198 { 199 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 200 201 OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); 202 if( pOutDev ) 203 { 204 Font aOldFont = pOutDev->GetFont(); 205 pOutDev->SetFont( maFont ); 206 207 sal_uLong nPairs = pOutDev->GetKerningPairCount(); 208 if ( nPairs ) 209 { 210 KerningPair* pData = new KerningPair[ nPairs ]; 211 pOutDev->GetKerningPairs( nPairs, pData ); 212 213 rnChars1 = ::com::sun::star::uno::Sequence<sal_Unicode>( nPairs ); 214 rnChars2 = ::com::sun::star::uno::Sequence<sal_Unicode>( nPairs ); 215 rnKerns = ::com::sun::star::uno::Sequence<sal_Int16>( nPairs ); 216 217 sal_Unicode* pChars1 = rnChars1.getArray(); 218 sal_Unicode* pChars2 = rnChars2.getArray(); 219 sal_Int16* pKerns = rnKerns.getArray(); 220 221 for ( sal_uLong n = 0; n < nPairs; n++ ) 222 { 223 pChars1[n] = pData[n].nChar1; 224 pChars2[n] = pData[n].nChar2; 225 pKerns[n] = sal::static_int_cast< sal_Int16 >(pData[n].nKern); 226 } 227 228 229 delete[] pData; 230 } 231 pOutDev->SetFont( aOldFont ); 232 } 233 } 234 235 // ::com::sun::star::awt::XFont2 236 sal_Bool VCLXFont::hasGlyphs( const ::rtl::OUString& aText ) 237 throw(::com::sun::star::uno::RuntimeException) 238 { 239 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 240 241 OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice ); 242 if ( pOutDev ) 243 { 244 String aStr( aText ); 245 if ( pOutDev->HasGlyphs( maFont, aStr, 0, aStr.Len() ) == STRING_LEN ) 246 { 247 return sal_True; 248 } 249 } 250 251 return sal_False; 252 } 253