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_canvas.hxx"
30 
31 #include <canvas/debug.hxx>
32 
33 #include <com/sun/star/rendering/PanoseProportion.hpp>
34 
35 #include <rtl/math.hxx>
36 #include <basegfx/numeric/ftools.hxx>
37 
38 #include <vcl/metric.hxx>
39 #include <i18npool/mslangid.hxx>
40 
41 #include "cairo_canvasfont.hxx"
42 #include "cairo_textlayout.hxx"
43 
44 using namespace ::com::sun::star;
45 
46 namespace cairocanvas
47 {
48     namespace
49     {
50         // Little helper to encapsulate locking into policy class
51         class LocalGuard
52         {
53         public:
54             LocalGuard() :
55                 aGuard( Application::GetSolarMutex() )
56             {
57         	}
58 
59             /// To be compatible with CanvasBase mutex concept
60             LocalGuard( const ::osl::Mutex& ) :
61                 aGuard( Application::GetSolarMutex() )
62             {
63         	}
64 
65         private:
66             ::vos::OGuard aGuard;
67         };
68     }
69 
70     CanvasFont::CanvasFont( const rendering::FontRequest& 					rFontRequest,
71                             const uno::Sequence< beans::PropertyValue >&	/*rExtraFontProperties*/,
72                             const geometry::Matrix2D& 						rFontMatrix,
73                             const SurfaceProviderRef&						rDevice ) :
74         CanvasFont_Base( m_aMutex ),
75         maFont( Font( rFontRequest.FontDescription.FamilyName,
76                       rFontRequest.FontDescription.StyleName,
77                       Size( 0, ::basegfx::fround(rFontRequest.CellSize) ) ) ),
78         maFontRequest( rFontRequest ),
79         mpRefDevice( rDevice )
80     {
81         maFont->SetAlign( ALIGN_BASELINE );
82         maFont->SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==com::sun::star::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE );
83         maFont->SetVertical( (rFontRequest.FontDescription.IsVertical==com::sun::star::util::TriState_YES) ? sal_True : sal_False );
84 
85         // TODO(F2): improve panose->vclenum conversion
86         maFont->SetWeight( static_cast<FontWeight>(rFontRequest.FontDescription.FontDescription.Weight) );
87         maFont->SetItalic( (rFontRequest.FontDescription.FontDescription.Letterform<=8) ? ITALIC_NONE : ITALIC_NORMAL );
88         maFont->SetPitch(
89                 rFontRequest.FontDescription.FontDescription.Proportion == rendering::PanoseProportion::MONO_SPACED
90                     ? PITCH_FIXED : PITCH_VARIABLE);
91 
92         maFont->SetLanguage(MsLangId::convertLocaleToLanguage(rFontRequest.Locale));
93 
94         // adjust to stretched/shrinked font
95         if( !::rtl::math::approxEqual( rFontMatrix.m00, rFontMatrix.m11) )
96         {
97             OutputDevice* pOutDev( mpRefDevice->getOutputDevice() );
98 
99             if( pOutDev )
100             {
101                 const bool bOldMapState( pOutDev->IsMapModeEnabled() );
102                 pOutDev->EnableMapMode(sal_False);
103 
104                 const Size aSize = pOutDev->GetFontMetric( *maFont ).GetSize();
105 
106                 const double fDividend( rFontMatrix.m10 + rFontMatrix.m11 );
107                 double fStretch = (rFontMatrix.m00 + rFontMatrix.m01);
108 
109                 if( !::basegfx::fTools::equalZero( fDividend) )
110                     fStretch /= fDividend;
111 
112                 const long nNewWidth = ::basegfx::fround( aSize.Width() * fStretch );
113 
114                 maFont->SetWidth( nNewWidth );
115 
116                 pOutDev->EnableMapMode(bOldMapState);
117             }
118         }
119     }
120 
121     void SAL_CALL CanvasFont::disposing()
122     {
123         LocalGuard aGuard;
124 
125         mpRefDevice.clear();
126     }
127 
128     uno::Reference< rendering::XTextLayout > SAL_CALL  CanvasFont::createTextLayout( const rendering::StringContext& aText, sal_Int8 nDirection, sal_Int64 nRandomSeed ) throw (uno::RuntimeException)
129     {
130         LocalGuard aGuard;
131 
132         if( !mpRefDevice.is() )
133             return uno::Reference< rendering::XTextLayout >(); // we're disposed
134 
135         return new TextLayout( aText,
136                                nDirection,
137                                nRandomSeed,
138                                Reference( this ),
139 							   mpRefDevice );
140     }
141 
142     rendering::FontRequest SAL_CALL  CanvasFont::getFontRequest(  ) throw (uno::RuntimeException)
143     {
144         LocalGuard aGuard;
145 
146         return maFontRequest;
147     }
148 
149     rendering::FontMetrics SAL_CALL  CanvasFont::getFontMetrics(  ) throw (uno::RuntimeException)
150     {
151         LocalGuard aGuard;
152 
153         // TODO(F1)
154         return rendering::FontMetrics();
155     }
156 
157     uno::Sequence< double > SAL_CALL  CanvasFont::getAvailableSizes(  ) throw (uno::RuntimeException)
158     {
159         LocalGuard aGuard;
160 
161         // TODO(F1)
162         return uno::Sequence< double >();
163     }
164 
165     uno::Sequence< beans::PropertyValue > SAL_CALL  CanvasFont::getExtraFontProperties(  ) throw (uno::RuntimeException)
166     {
167         LocalGuard aGuard;
168 
169         // TODO(F1)
170         return uno::Sequence< beans::PropertyValue >();
171     }
172 
173 #define IMPLEMENTATION_NAME "CairoCanvas::CanvasFont"
174 #define SERVICE_NAME "com.sun.star.rendering.CanvasFont"
175 
176     ::rtl::OUString SAL_CALL CanvasFont::getImplementationName() throw( uno::RuntimeException )
177     {
178         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
179     }
180 
181     sal_Bool SAL_CALL CanvasFont::supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException )
182     {
183         return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
184     }
185 
186     uno::Sequence< ::rtl::OUString > SAL_CALL CanvasFont::getSupportedServiceNames()  throw( uno::RuntimeException )
187     {
188         uno::Sequence< ::rtl::OUString > aRet(1);
189         aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
190 
191         return aRet;
192     }
193 
194     ::Font CanvasFont::getVCLFont() const
195     {
196         return *maFont;
197     }
198 }
199