1464702f4SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3464702f4SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4464702f4SAndrew Rist * or more contributor license agreements. See the NOTICE file 5464702f4SAndrew Rist * distributed with this work for additional information 6464702f4SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7464702f4SAndrew Rist * to you under the Apache License, Version 2.0 (the 8464702f4SAndrew Rist * "License"); you may not use this file except in compliance 9464702f4SAndrew Rist * with the License. You may obtain a copy of the License at 10464702f4SAndrew Rist * 11464702f4SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12464702f4SAndrew Rist * 13464702f4SAndrew Rist * Unless required by applicable law or agreed to in writing, 14464702f4SAndrew Rist * software distributed under the License is distributed on an 15464702f4SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16464702f4SAndrew Rist * KIND, either express or implied. See the License for the 17464702f4SAndrew Rist * specific language governing permissions and limitations 18464702f4SAndrew Rist * under the License. 19464702f4SAndrew Rist * 20464702f4SAndrew Rist *************************************************************/ 21464702f4SAndrew Rist 22464702f4SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <drawinglayer/primitive2d/textlayoutdevice.hxx> 28cdf0e10cSrcweir #include <vcl/timer.hxx> 29cdf0e10cSrcweir #include <vcl/virdev.hxx> 30cdf0e10cSrcweir #include <vcl/font.hxx> 31cdf0e10cSrcweir #include <vcl/metric.hxx> 32cdf0e10cSrcweir #include <i18npool/mslangid.hxx> 33cdf0e10cSrcweir #include <drawinglayer/primitive2d/textprimitive2d.hxx> 34cdf0e10cSrcweir #include <vcl/svapp.hxx> 35cdf0e10cSrcweir 36cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 37cdf0e10cSrcweir // VDev RevDevice provider 38cdf0e10cSrcweir 39cdf0e10cSrcweir namespace 40cdf0e10cSrcweir { 41cdf0e10cSrcweir class ImpTimedRefDev : public Timer 42cdf0e10cSrcweir { 43cdf0e10cSrcweir ImpTimedRefDev** mppStaticPointerOnMe; 44cdf0e10cSrcweir VirtualDevice* mpVirDev; 45cdf0e10cSrcweir sal_uInt32 mnUseCount; 46cdf0e10cSrcweir 47cdf0e10cSrcweir public: 48cdf0e10cSrcweir ImpTimedRefDev(ImpTimedRefDev** ppStaticPointerOnMe); 49cdf0e10cSrcweir ~ImpTimedRefDev(); 50cdf0e10cSrcweir virtual void Timeout(); 51cdf0e10cSrcweir 52cdf0e10cSrcweir VirtualDevice& acquireVirtualDevice(); 53cdf0e10cSrcweir void releaseVirtualDevice(); 54cdf0e10cSrcweir }; 55cdf0e10cSrcweir ImpTimedRefDev(ImpTimedRefDev ** ppStaticPointerOnMe)56cdf0e10cSrcweir ImpTimedRefDev::ImpTimedRefDev(ImpTimedRefDev** ppStaticPointerOnMe) 57cdf0e10cSrcweir : mppStaticPointerOnMe(ppStaticPointerOnMe), 58cdf0e10cSrcweir mpVirDev(0L), 59cdf0e10cSrcweir mnUseCount(0L) 60cdf0e10cSrcweir { 61cdf0e10cSrcweir SetTimeout(3L * 60L * 1000L); // three minutes 62cdf0e10cSrcweir Start(); 63cdf0e10cSrcweir } 64cdf0e10cSrcweir ~ImpTimedRefDev()65cdf0e10cSrcweir ImpTimedRefDev::~ImpTimedRefDev() 66cdf0e10cSrcweir { 67cdf0e10cSrcweir OSL_ENSURE(0L == mnUseCount, "destruction of a still used ImpTimedRefDev (!)"); 68cdf0e10cSrcweir 69cdf0e10cSrcweir if(mppStaticPointerOnMe && *mppStaticPointerOnMe) 70cdf0e10cSrcweir { 71cdf0e10cSrcweir *mppStaticPointerOnMe = 0L; 72cdf0e10cSrcweir } 73cdf0e10cSrcweir 74cdf0e10cSrcweir if(mpVirDev) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir delete mpVirDev; 77cdf0e10cSrcweir } 78cdf0e10cSrcweir } 79cdf0e10cSrcweir Timeout()80cdf0e10cSrcweir void ImpTimedRefDev::Timeout() 81cdf0e10cSrcweir { 82cdf0e10cSrcweir // for obvious reasons, do not call anything after this 83cdf0e10cSrcweir delete (this); 84cdf0e10cSrcweir } 85cdf0e10cSrcweir acquireVirtualDevice()86cdf0e10cSrcweir VirtualDevice& ImpTimedRefDev::acquireVirtualDevice() 87cdf0e10cSrcweir { 88cdf0e10cSrcweir if(!mpVirDev) 89cdf0e10cSrcweir { 90cdf0e10cSrcweir mpVirDev = new VirtualDevice(); 91cdf0e10cSrcweir mpVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_MSO1 ); 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir if(!mnUseCount) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir Stop(); 97cdf0e10cSrcweir } 98cdf0e10cSrcweir 99cdf0e10cSrcweir mnUseCount++; 100cdf0e10cSrcweir 101cdf0e10cSrcweir return *mpVirDev; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir releaseVirtualDevice()104cdf0e10cSrcweir void ImpTimedRefDev::releaseVirtualDevice() 105cdf0e10cSrcweir { 106cdf0e10cSrcweir OSL_ENSURE(mnUseCount, "mismatch call number to releaseVirtualDevice() (!)"); 107cdf0e10cSrcweir mnUseCount--; 108cdf0e10cSrcweir 109cdf0e10cSrcweir if(!mnUseCount) 110cdf0e10cSrcweir { 111cdf0e10cSrcweir Start(); 112cdf0e10cSrcweir } 113cdf0e10cSrcweir } 114cdf0e10cSrcweir } // end of anonymous namespace 115cdf0e10cSrcweir 116cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 117cdf0e10cSrcweir // access to one global ImpTimedRefDev incarnation in namespace drawinglayer::primitive 118cdf0e10cSrcweir 119cdf0e10cSrcweir namespace drawinglayer 120cdf0e10cSrcweir { 121cdf0e10cSrcweir namespace primitive2d 122cdf0e10cSrcweir { 123cdf0e10cSrcweir // static pointer here 124cdf0e10cSrcweir static ImpTimedRefDev* pImpGlobalRefDev = 0L; 125cdf0e10cSrcweir 126cdf0e10cSrcweir // static methods here acquireGlobalVirtualDevice()127cdf0e10cSrcweir VirtualDevice& acquireGlobalVirtualDevice() 128cdf0e10cSrcweir { 129cdf0e10cSrcweir if(!pImpGlobalRefDev) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir pImpGlobalRefDev = new ImpTimedRefDev(&pImpGlobalRefDev); 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir return pImpGlobalRefDev->acquireVirtualDevice(); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir releaseGlobalVirtualDevice()137cdf0e10cSrcweir void releaseGlobalVirtualDevice() 138cdf0e10cSrcweir { 139cdf0e10cSrcweir OSL_ENSURE(pImpGlobalRefDev, "releaseGlobalVirtualDevice() without prior acquireGlobalVirtualDevice() call(!)"); 140cdf0e10cSrcweir pImpGlobalRefDev->releaseVirtualDevice(); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir TextLayouterDevice()143cdf0e10cSrcweir TextLayouterDevice::TextLayouterDevice() 144cdf0e10cSrcweir : mrDevice(acquireGlobalVirtualDevice()) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir } 147cdf0e10cSrcweir ~TextLayouterDevice()148cdf0e10cSrcweir TextLayouterDevice::~TextLayouterDevice() 149cdf0e10cSrcweir { 150cdf0e10cSrcweir releaseGlobalVirtualDevice(); 151cdf0e10cSrcweir } 152cdf0e10cSrcweir setFont(const Font & rFont)153cdf0e10cSrcweir void TextLayouterDevice::setFont(const Font& rFont) 154cdf0e10cSrcweir { 155cdf0e10cSrcweir mrDevice.SetFont( rFont ); 156cdf0e10cSrcweir } 157cdf0e10cSrcweir setFontAttribute(const attribute::FontAttribute & rFontAttribute,double fFontScaleX,double fFontScaleY,const::com::sun::star::lang::Locale & rLocale)158cdf0e10cSrcweir void TextLayouterDevice::setFontAttribute( 159cdf0e10cSrcweir const attribute::FontAttribute& rFontAttribute, 160cdf0e10cSrcweir double fFontScaleX, 161cdf0e10cSrcweir double fFontScaleY, 162cdf0e10cSrcweir const ::com::sun::star::lang::Locale& rLocale) 163cdf0e10cSrcweir { 164cdf0e10cSrcweir setFont(getVclFontFromFontAttribute( 165cdf0e10cSrcweir rFontAttribute, 166cdf0e10cSrcweir fFontScaleX, 167cdf0e10cSrcweir fFontScaleY, 168cdf0e10cSrcweir 0.0, 169cdf0e10cSrcweir rLocale)); 170cdf0e10cSrcweir } 171cdf0e10cSrcweir getOverlineOffset() const172cdf0e10cSrcweir double TextLayouterDevice::getOverlineOffset() const 173cdf0e10cSrcweir { 174cdf0e10cSrcweir const ::FontMetric& rMetric = mrDevice.GetFontMetric(); 175cdf0e10cSrcweir double fRet = (rMetric.GetIntLeading() / 2.0) - rMetric.GetAscent(); 176cdf0e10cSrcweir return fRet; 177cdf0e10cSrcweir } 178cdf0e10cSrcweir getUnderlineOffset() const179cdf0e10cSrcweir double TextLayouterDevice::getUnderlineOffset() const 180cdf0e10cSrcweir { 181cdf0e10cSrcweir const ::FontMetric& rMetric = mrDevice.GetFontMetric(); 182cdf0e10cSrcweir double fRet = rMetric.GetDescent() / 2.0; 183cdf0e10cSrcweir return fRet; 184cdf0e10cSrcweir } 185cdf0e10cSrcweir getStrikeoutOffset() const186cdf0e10cSrcweir double TextLayouterDevice::getStrikeoutOffset() const 187cdf0e10cSrcweir { 188cdf0e10cSrcweir const ::FontMetric& rMetric = mrDevice.GetFontMetric(); 189cdf0e10cSrcweir double fRet = (rMetric.GetAscent() - rMetric.GetIntLeading()) / 3.0; 190cdf0e10cSrcweir return fRet; 191cdf0e10cSrcweir } 192cdf0e10cSrcweir getOverlineHeight() const193cdf0e10cSrcweir double TextLayouterDevice::getOverlineHeight() const 194cdf0e10cSrcweir { 195cdf0e10cSrcweir const ::FontMetric& rMetric = mrDevice.GetFontMetric(); 196cdf0e10cSrcweir double fRet = rMetric.GetIntLeading() / 2.5; 197cdf0e10cSrcweir return fRet; 198cdf0e10cSrcweir } 199cdf0e10cSrcweir getUnderlineHeight() const200cdf0e10cSrcweir double TextLayouterDevice::getUnderlineHeight() const 201cdf0e10cSrcweir { 202cdf0e10cSrcweir const ::FontMetric& rMetric = mrDevice.GetFontMetric(); 203cdf0e10cSrcweir double fRet = rMetric.GetDescent() / 4.0; 204cdf0e10cSrcweir return fRet; 205cdf0e10cSrcweir } 206cdf0e10cSrcweir getTextHeight() const207cdf0e10cSrcweir double TextLayouterDevice::getTextHeight() const 208cdf0e10cSrcweir { 209cdf0e10cSrcweir return mrDevice.GetTextHeight(); 210cdf0e10cSrcweir } 211cdf0e10cSrcweir getTextWidth(const String & rText,sal_uInt32 nIndex,sal_uInt32 nLength) const212cdf0e10cSrcweir double TextLayouterDevice::getTextWidth( 213cdf0e10cSrcweir const String& rText, 214cdf0e10cSrcweir sal_uInt32 nIndex, 215cdf0e10cSrcweir sal_uInt32 nLength) const 216cdf0e10cSrcweir { 217cdf0e10cSrcweir return mrDevice.GetTextWidth(rText, nIndex, nLength); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir getTextOutlines(basegfx::B2DPolyPolygonVector & rB2DPolyPolyVector,const String & rText,sal_uInt32 nIndex,sal_uInt32 nLength,const::std::vector<double> & rDXArray) const220cdf0e10cSrcweir bool TextLayouterDevice::getTextOutlines( 221cdf0e10cSrcweir basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector, 222cdf0e10cSrcweir const String& rText, 223cdf0e10cSrcweir sal_uInt32 nIndex, 224cdf0e10cSrcweir sal_uInt32 nLength, 225cdf0e10cSrcweir const ::std::vector< double >& rDXArray) const 226cdf0e10cSrcweir { 227cdf0e10cSrcweir const sal_uInt32 nDXArrayCount(rDXArray.size()); 228cdf0e10cSrcweir sal_uInt32 nTextLength(nLength); 229cdf0e10cSrcweir const sal_uInt32 nStringLength(rText.Len()); 230cdf0e10cSrcweir 231cdf0e10cSrcweir if(nTextLength + nIndex > nStringLength) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir nTextLength = nStringLength - nIndex; 234cdf0e10cSrcweir } 235cdf0e10cSrcweir 236cdf0e10cSrcweir if(nDXArrayCount) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir OSL_ENSURE(nDXArrayCount == nTextLength, "DXArray size does not correspond to text portion size (!)"); 239cdf0e10cSrcweir std::vector< sal_Int32 > aIntegerDXArray(nDXArrayCount); 240cdf0e10cSrcweir 241cdf0e10cSrcweir for(sal_uInt32 a(0); a < nDXArrayCount; a++) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir aIntegerDXArray[a] = basegfx::fround(rDXArray[a]); 244cdf0e10cSrcweir } 245cdf0e10cSrcweir 246cdf0e10cSrcweir return mrDevice.GetTextOutlines( 247cdf0e10cSrcweir rB2DPolyPolyVector, 248cdf0e10cSrcweir rText, 249cdf0e10cSrcweir nIndex, 250cdf0e10cSrcweir nIndex, 251cdf0e10cSrcweir nLength, 252cdf0e10cSrcweir true, 253cdf0e10cSrcweir 0, 254cdf0e10cSrcweir &(aIntegerDXArray[0])); 255cdf0e10cSrcweir } 256cdf0e10cSrcweir else 257cdf0e10cSrcweir { 258cdf0e10cSrcweir return mrDevice.GetTextOutlines( 259cdf0e10cSrcweir rB2DPolyPolyVector, 260cdf0e10cSrcweir rText, 261cdf0e10cSrcweir nIndex, 262cdf0e10cSrcweir nIndex, 263cdf0e10cSrcweir nLength, 264cdf0e10cSrcweir true, 265cdf0e10cSrcweir 0, 266cdf0e10cSrcweir 0); 267cdf0e10cSrcweir } 268cdf0e10cSrcweir } 269cdf0e10cSrcweir getTextBoundRect(const String & rText,sal_uInt32 nIndex,sal_uInt32 nLength) const270cdf0e10cSrcweir basegfx::B2DRange TextLayouterDevice::getTextBoundRect( 271cdf0e10cSrcweir const String& rText, 272cdf0e10cSrcweir sal_uInt32 nIndex, 273cdf0e10cSrcweir sal_uInt32 nLength) const 274cdf0e10cSrcweir { 275cdf0e10cSrcweir sal_uInt32 nTextLength(nLength); 276cdf0e10cSrcweir const sal_uInt32 nStringLength(rText.Len()); 277cdf0e10cSrcweir 278cdf0e10cSrcweir if(nTextLength + nIndex > nStringLength) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir nTextLength = nStringLength - nIndex; 281cdf0e10cSrcweir } 282cdf0e10cSrcweir 283cdf0e10cSrcweir if(nTextLength) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir Rectangle aRect; 286cdf0e10cSrcweir 287cdf0e10cSrcweir mrDevice.GetTextBoundRect( 288cdf0e10cSrcweir aRect, 289cdf0e10cSrcweir rText, 290cdf0e10cSrcweir nIndex, 291cdf0e10cSrcweir nIndex, 292cdf0e10cSrcweir nLength); 293cdf0e10cSrcweir 294cdf0e10cSrcweir // #i104432#, #i102556# take empty results into account 295cdf0e10cSrcweir if(!aRect.IsEmpty()) 296cdf0e10cSrcweir { 297cdf0e10cSrcweir return basegfx::B2DRange( 298cdf0e10cSrcweir aRect.Left(), aRect.Top(), 299cdf0e10cSrcweir aRect.Right(), aRect.Bottom()); 300cdf0e10cSrcweir } 301cdf0e10cSrcweir } 302cdf0e10cSrcweir 303cdf0e10cSrcweir return basegfx::B2DRange(); 304cdf0e10cSrcweir } 305cdf0e10cSrcweir getFontAscent() const306cdf0e10cSrcweir double TextLayouterDevice::getFontAscent() const 307cdf0e10cSrcweir { 308cdf0e10cSrcweir const ::FontMetric& rMetric = mrDevice.GetFontMetric(); 309cdf0e10cSrcweir return rMetric.GetAscent(); 310cdf0e10cSrcweir } 311cdf0e10cSrcweir getFontDescent() const312cdf0e10cSrcweir double TextLayouterDevice::getFontDescent() const 313cdf0e10cSrcweir { 314cdf0e10cSrcweir const ::FontMetric& rMetric = mrDevice.GetFontMetric(); 315cdf0e10cSrcweir return rMetric.GetDescent(); 316cdf0e10cSrcweir } 317cdf0e10cSrcweir addTextRectActions(const Rectangle & rRectangle,const String & rText,sal_uInt16 nStyle,GDIMetaFile & rGDIMetaFile) const318cdf0e10cSrcweir void TextLayouterDevice::addTextRectActions( 319cdf0e10cSrcweir const Rectangle& rRectangle, 320cdf0e10cSrcweir const String& rText, 321cdf0e10cSrcweir sal_uInt16 nStyle, 322cdf0e10cSrcweir GDIMetaFile& rGDIMetaFile) const 323cdf0e10cSrcweir { 324cdf0e10cSrcweir mrDevice.AddTextRectActions( 325cdf0e10cSrcweir rRectangle, rText, nStyle, rGDIMetaFile); 326cdf0e10cSrcweir } 327cdf0e10cSrcweir getTextArray(const String & rText,sal_uInt32 nIndex,sal_uInt32 nLength) const328cdf0e10cSrcweir ::std::vector< double > TextLayouterDevice::getTextArray( 329cdf0e10cSrcweir const String& rText, 330cdf0e10cSrcweir sal_uInt32 nIndex, 331cdf0e10cSrcweir sal_uInt32 nLength) const 332cdf0e10cSrcweir { 333cdf0e10cSrcweir ::std::vector< double > aRetval; 334cdf0e10cSrcweir sal_uInt32 nTextLength(nLength); 335cdf0e10cSrcweir const sal_uInt32 nStringLength(rText.Len()); 336cdf0e10cSrcweir 337cdf0e10cSrcweir if(nTextLength + nIndex > nStringLength) 338cdf0e10cSrcweir { 339cdf0e10cSrcweir nTextLength = nStringLength - nIndex; 340cdf0e10cSrcweir } 341cdf0e10cSrcweir 342cdf0e10cSrcweir if(nTextLength) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir aRetval.reserve(nTextLength); 345cc213d65SHerbert Dürr ::std::vector<sal_Int32> aDXArray( nTextLength); 346cc213d65SHerbert Dürr mrDevice.GetTextArray(rText, &aDXArray[0], nIndex, nLength); 347cdf0e10cSrcweir 348cdf0e10cSrcweir for(sal_uInt32 a(0); a < nTextLength; a++) 349cdf0e10cSrcweir { 350cc213d65SHerbert Dürr aRetval.push_back(aDXArray[a]); 351cdf0e10cSrcweir } 352cdf0e10cSrcweir } 353cdf0e10cSrcweir 354cdf0e10cSrcweir return aRetval; 355cdf0e10cSrcweir } 356cdf0e10cSrcweir 357cdf0e10cSrcweir } // end of namespace primitive2d 358cdf0e10cSrcweir } // end of namespace drawinglayer 359cdf0e10cSrcweir 360cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 361cdf0e10cSrcweir // helper methods for vcl font handling 362cdf0e10cSrcweir 363cdf0e10cSrcweir namespace drawinglayer 364cdf0e10cSrcweir { 365cdf0e10cSrcweir namespace primitive2d 366cdf0e10cSrcweir { getVclFontFromFontAttribute(const attribute::FontAttribute & rFontAttribute,double fFontScaleX,double fFontScaleY,double fFontRotation,const::com::sun::star::lang::Locale & rLocale)367cdf0e10cSrcweir Font getVclFontFromFontAttribute( 368cdf0e10cSrcweir const attribute::FontAttribute& rFontAttribute, 369cdf0e10cSrcweir double fFontScaleX, 370cdf0e10cSrcweir double fFontScaleY, 371cdf0e10cSrcweir double fFontRotation, 372cdf0e10cSrcweir const ::com::sun::star::lang::Locale& rLocale) 373cdf0e10cSrcweir { 374cdf0e10cSrcweir // detect FontScaling 375cdf0e10cSrcweir const sal_uInt32 nHeight(basegfx::fround(fabs(fFontScaleY))); 376cdf0e10cSrcweir const sal_uInt32 nWidth(basegfx::fround(fabs(fFontScaleX))); 377cdf0e10cSrcweir const bool bFontIsScaled(nHeight != nWidth); 378cdf0e10cSrcweir 379cdf0e10cSrcweir #ifdef WIN32 380cdf0e10cSrcweir // for WIN32 systems, start with creating an unscaled font. If FontScaling 381cdf0e10cSrcweir // is wanted, that width needs to be adapted using FontMetric again to get a 382cdf0e10cSrcweir // width of the unscaled font 383cdf0e10cSrcweir Font aRetval( 384cdf0e10cSrcweir rFontAttribute.getFamilyName(), 385cdf0e10cSrcweir rFontAttribute.getStyleName(), 386cdf0e10cSrcweir Size(0, nHeight)); 387cdf0e10cSrcweir #else 388cdf0e10cSrcweir // for non-WIN32 systems things are easier since these accept a Font creation 389cdf0e10cSrcweir // with initially nWidth != nHeight for FontScaling. Despite that, use zero for 390*6d53c851Smseidel // FontWidth when no scaling is used to explicitly have that zero when e.g. the 391cdf0e10cSrcweir // Font would be recorded in a MetaFile (The MetaFile FontAction WILL record a 392cdf0e10cSrcweir // set FontWidth; import that in a WIN32 system, and trouble is there) 393cdf0e10cSrcweir Font aRetval( 394cdf0e10cSrcweir rFontAttribute.getFamilyName(), 395cdf0e10cSrcweir rFontAttribute.getStyleName(), 396cdf0e10cSrcweir Size(bFontIsScaled ? nWidth : 0, nHeight)); 397cdf0e10cSrcweir #endif 398cdf0e10cSrcweir // define various other FontAttribute 399cdf0e10cSrcweir aRetval.SetAlign(ALIGN_BASELINE); 400cdf0e10cSrcweir aRetval.SetCharSet(rFontAttribute.getSymbol() ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE); 401cdf0e10cSrcweir aRetval.SetVertical(rFontAttribute.getVertical() ? sal_True : sal_False); 402cdf0e10cSrcweir aRetval.SetWeight(static_cast<FontWeight>(rFontAttribute.getWeight())); 403cdf0e10cSrcweir aRetval.SetItalic(rFontAttribute.getItalic() ? ITALIC_NORMAL : ITALIC_NONE); 404cdf0e10cSrcweir aRetval.SetOutline(rFontAttribute.getOutline()); 405cdf0e10cSrcweir aRetval.SetPitch(rFontAttribute.getMonospaced() ? PITCH_FIXED : PITCH_VARIABLE); 406cdf0e10cSrcweir aRetval.SetLanguage(MsLangId::convertLocaleToLanguage(rLocale)); 407cdf0e10cSrcweir 408cdf0e10cSrcweir #ifdef WIN32 409cdf0e10cSrcweir // for WIN32 systems, correct the FontWidth if FontScaling is used 410cdf0e10cSrcweir if(bFontIsScaled && nHeight > 0) 411cdf0e10cSrcweir { 412cdf0e10cSrcweir const FontMetric aUnscaledFontMetric(Application::GetDefaultDevice()->GetFontMetric(aRetval)); 413cdf0e10cSrcweir 414cdf0e10cSrcweir if(aUnscaledFontMetric.GetWidth() > 0) 415cdf0e10cSrcweir { 416cdf0e10cSrcweir const double fScaleFactor((double)nWidth / (double)nHeight); 417cdf0e10cSrcweir const sal_uInt32 nScaledWidth(basegfx::fround((double)aUnscaledFontMetric.GetWidth() * fScaleFactor)); 418cdf0e10cSrcweir aRetval.SetWidth(nScaledWidth); 419cdf0e10cSrcweir } 420cdf0e10cSrcweir } 421cdf0e10cSrcweir #endif 422cdf0e10cSrcweir // handle FontRotation (if defined) 423cdf0e10cSrcweir if(!basegfx::fTools::equalZero(fFontRotation)) 424cdf0e10cSrcweir { 425cdf0e10cSrcweir sal_Int16 aRotate10th((sal_Int16)(fFontRotation * (-1800.0/F_PI))); 426cdf0e10cSrcweir aRetval.SetOrientation(aRotate10th % 3600); 427cdf0e10cSrcweir } 428cdf0e10cSrcweir 429cdf0e10cSrcweir return aRetval; 430cdf0e10cSrcweir } 431cdf0e10cSrcweir getFontAttributeFromVclFont(basegfx::B2DVector & o_rSize,const Font & rFont,bool bRTL,bool bBiDiStrong)432cdf0e10cSrcweir attribute::FontAttribute getFontAttributeFromVclFont( 433cdf0e10cSrcweir basegfx::B2DVector& o_rSize, 434cdf0e10cSrcweir const Font& rFont, 435cdf0e10cSrcweir bool bRTL, 436cdf0e10cSrcweir bool bBiDiStrong) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir const attribute::FontAttribute aRetval( 439cdf0e10cSrcweir rFont.GetName(), 440cdf0e10cSrcweir rFont.GetStyleName(), 441cdf0e10cSrcweir static_cast<sal_uInt16>(rFont.GetWeight()), 442cdf0e10cSrcweir RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet(), 443cdf0e10cSrcweir rFont.IsVertical(), 444cdf0e10cSrcweir ITALIC_NONE != rFont.GetItalic(), 445cdf0e10cSrcweir PITCH_FIXED == rFont.GetPitch(), 446cdf0e10cSrcweir rFont.IsOutline(), 447cdf0e10cSrcweir bRTL, 448cdf0e10cSrcweir bBiDiStrong); 449cdf0e10cSrcweir // TODO: eKerning 450cdf0e10cSrcweir 451cdf0e10cSrcweir // set FontHeight and init to no FontScaling 452cdf0e10cSrcweir o_rSize.setY(rFont.GetSize().getHeight() > 0 ? rFont.GetSize().getHeight() : 0); 453cdf0e10cSrcweir o_rSize.setX(o_rSize.getY()); 454cdf0e10cSrcweir 455cdf0e10cSrcweir #ifdef WIN32 456cdf0e10cSrcweir // for WIN32 systems, the FontScaling at the Font is detected by 457cdf0e10cSrcweir // checking that FontWidth != 0. When FontScaling is used, WIN32 458cdf0e10cSrcweir // needs to do extra stuff to detect the correct width (since it's 459cdf0e10cSrcweir // zero and not equal the font height) and it's relationship to 460cdf0e10cSrcweir // the height 461cdf0e10cSrcweir if(rFont.GetSize().getWidth() > 0) 462cdf0e10cSrcweir { 463cdf0e10cSrcweir Font aUnscaledFont(rFont); 464cdf0e10cSrcweir aUnscaledFont.SetWidth(0); 465cdf0e10cSrcweir const FontMetric aUnscaledFontMetric(Application::GetDefaultDevice()->GetFontMetric(aUnscaledFont)); 466cdf0e10cSrcweir 467cdf0e10cSrcweir if(aUnscaledFontMetric.GetWidth() > 0) 468cdf0e10cSrcweir { 469cdf0e10cSrcweir const double fScaleFactor((double)rFont.GetSize().getWidth() / (double)aUnscaledFontMetric.GetWidth()); 470cdf0e10cSrcweir o_rSize.setX(fScaleFactor * o_rSize.getY()); 471cdf0e10cSrcweir } 472cdf0e10cSrcweir } 473cdf0e10cSrcweir #else 474cdf0e10cSrcweir // For non-WIN32 systems the detection is the same, but the value 475cdf0e10cSrcweir // is easier achieved since width == height is interpreted as no 476cdf0e10cSrcweir // scaling. Ergo, Width == 0 means width == height, and width != 0 477cdf0e10cSrcweir // means the scaling is in the direct relation of width to height 478cdf0e10cSrcweir if(rFont.GetSize().getWidth() > 0) 479cdf0e10cSrcweir { 480cdf0e10cSrcweir o_rSize.setX((double)rFont.GetSize().getWidth()); 481cdf0e10cSrcweir } 482cdf0e10cSrcweir #endif 483cdf0e10cSrcweir return aRetval; 484cdf0e10cSrcweir } 485cdf0e10cSrcweir } // end of namespace primitive2d 486cdf0e10cSrcweir } // end of namespace drawinglayer 487cdf0e10cSrcweir 488cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 489cdf0e10cSrcweir // eof 490