1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_sd.hxx"
25 
26 #include "SlideRenderer.hxx"
27 #include "sdpage.hxx"
28 #include <toolkit/helper/vclunohelper.hxx>
29 #include <vos/mutex.hxx>
30 #include <vcl/svapp.hxx>
31 #include <cppcanvas/vclfactory.hxx>
32 
33 using namespace ::com::sun::star;
34 using namespace ::com::sun::star::uno;
35 using ::rtl::OUString;
36 
37 namespace sd { namespace presenter {
38 
39 //===== Service ===============================================================
40 
41 Reference<XInterface> SAL_CALL SlideRenderer_createInstance (
42     const Reference<XComponentContext>& rxContext)
43 {
44     return Reference<XInterface>(static_cast<XWeak*>(new SlideRenderer(rxContext)));
45 }
46 
47 
48 
49 
50 ::rtl::OUString SlideRenderer_getImplementationName (void) throw(RuntimeException)
51 {
52     return OUString::createFromAscii("com.sun.star.comp.Draw.SlideRenderer");
53 }
54 
55 
56 
57 
58 Sequence<rtl::OUString> SAL_CALL SlideRenderer_getSupportedServiceNames (void)
59     throw (RuntimeException)
60 {
61 	static const ::rtl::OUString sServiceName(
62         ::rtl::OUString::createFromAscii("com.sun.star.drawing.SlideRenderer"));
63 	return Sequence<rtl::OUString>(&sServiceName, 1);
64 }
65 
66 
67 
68 
69 //===== SlideRenderer ==========================================================
70 
71 SlideRenderer::SlideRenderer (const Reference<XComponentContext>& rxContext)
72     : SlideRendererInterfaceBase(m_aMutex),
73       maPreviewRenderer()
74 {
75     (void)rxContext;
76 }
77 
78 
79 
80 
81 SlideRenderer::~SlideRenderer (void)
82 {
83 }
84 
85 
86 
87 
88 void SAL_CALL SlideRenderer::disposing (void)
89 {
90 }
91 
92 
93 
94 
95 //----- XInitialization -------------------------------------------------------
96 
97 void SAL_CALL SlideRenderer::initialize (const Sequence<Any>& rArguments)
98     throw (Exception, RuntimeException)
99 {
100     ThrowIfDisposed();
101 
102     if (rArguments.getLength() == 0)
103     {
104         try
105         {
106         }
107         catch (RuntimeException&)
108         {
109             throw;
110         }
111     }
112     else
113     {
114         throw RuntimeException(
115             OUString::createFromAscii("SlideRenderer: invalid number of arguments"),
116                 static_cast<XWeak*>(this));
117     }
118 }
119 
120 
121 
122 
123 //----- XSlideRenderer --------------------------------------------------------
124 
125 Reference<awt::XBitmap> SlideRenderer::createPreview (
126     const Reference<drawing::XDrawPage>& rxSlide,
127     const awt::Size& rMaximalSize,
128     sal_Int16 nSuperSampleFactor)
129     throw (css::uno::RuntimeException)
130 {
131     ThrowIfDisposed();
132 	::vos::OGuard aGuard (Application::GetSolarMutex());
133 
134     return VCLUnoHelper::CreateBitmap(
135         CreatePreview(rxSlide, rMaximalSize, nSuperSampleFactor));
136 }
137 
138 
139 
140 
141 Reference<rendering::XBitmap> SlideRenderer::createPreviewForCanvas (
142     const Reference<drawing::XDrawPage>& rxSlide,
143     const awt::Size& rMaximalSize,
144     sal_Int16 nSuperSampleFactor,
145     const Reference<rendering::XCanvas>& rxCanvas)
146     throw (css::uno::RuntimeException)
147 {
148     ThrowIfDisposed();
149 	::vos::OGuard aGuard (Application::GetSolarMutex());
150 
151     cppcanvas::BitmapCanvasSharedPtr pCanvas (cppcanvas::VCLFactory::getInstance().createCanvas(
152         Reference<rendering::XBitmapCanvas>(rxCanvas, UNO_QUERY)));
153     if (pCanvas.get() != NULL)
154         return cppcanvas::VCLFactory::getInstance().createBitmap(
155             pCanvas,
156             CreatePreview(rxSlide, rMaximalSize, nSuperSampleFactor))->getUNOBitmap();
157     else
158         return NULL;
159 }
160 
161 
162 
163 
164 awt::Size SAL_CALL SlideRenderer::calculatePreviewSize (
165     double nSlideAspectRatio,
166     const awt::Size& rMaximalSize)
167     throw (css::uno::RuntimeException)
168 {
169     if (rMaximalSize.Width <= 0
170         || rMaximalSize.Height <= 0
171         || nSlideAspectRatio <= 0)
172     {
173         return awt::Size(0,0);
174     }
175 
176     const double nWindowAspectRatio (double(rMaximalSize.Width) / double(rMaximalSize.Height));
177     if (nSlideAspectRatio < nWindowAspectRatio)
178         return awt::Size(
179             sal::static_int_cast<sal_Int32>(rMaximalSize.Height * nSlideAspectRatio),
180             rMaximalSize.Height);
181     else
182         return awt::Size(
183             rMaximalSize.Width,
184             sal::static_int_cast<sal_Int32>(rMaximalSize.Width / nSlideAspectRatio));
185 }
186 
187 
188 
189 
190 //-----------------------------------------------------------------------------
191 
192 BitmapEx SlideRenderer::CreatePreview (
193     const Reference<drawing::XDrawPage>& rxSlide,
194     const awt::Size& rMaximalSize,
195     sal_Int16 nSuperSampleFactor)
196     throw (css::uno::RuntimeException)
197 {
198     const SdPage* pPage = SdPage::getImplementation(rxSlide);
199     if (pPage == NULL)
200         throw lang::IllegalArgumentException(
201             OUString::createFromAscii("SlideRenderer::createPreview() called with invalid slide"),
202             static_cast<XWeak*>(this),
203             0);
204 
205     // Determine the size of the current slide and its aspect ratio.
206     Size aPageSize = pPage->GetSize();
207     if (aPageSize.Height() <= 0)
208         throw lang::IllegalArgumentException(
209             OUString::createFromAscii("SlideRenderer::createPreview() called with invalid size"),
210             static_cast<XWeak*>(this),
211             1);
212 
213     // Compare with the aspect ratio of the window (which rMaximalSize
214     // assumed to be) and calculate the size of the preview so that it
215     // a) will have the aspect ratio of the page and
216     // b) will be as large as possible.
217     awt::Size aPreviewSize (calculatePreviewSize(
218         double(aPageSize.Width()) / double(aPageSize.Height()),
219         rMaximalSize));
220     if (aPreviewSize.Width <= 0 || aPreviewSize.Height <= 0)
221         return BitmapEx();
222 
223     // Make sure that the super sample factor has a sane value.
224     sal_Int16 nFactor (nSuperSampleFactor);
225     if (nFactor < 1)
226         nFactor = 1;
227     else if (nFactor > 10)
228         nFactor = 10;
229 
230     // Create the preview.  When the super sample factor n is greater than 1
231     // then a preview is created in size (n*width, n*height) and then scaled
232     // down to (width, height).  This is a poor mans antialiasing for the
233     // time being.  When we have true antialiasing support this workaround
234     // can be removed.
235     const Image aPreview = maPreviewRenderer.RenderPage (
236         pPage,
237         Size(aPreviewSize.Width*nFactor, aPreviewSize.Height*nFactor),
238         ::rtl::OUString());
239     if (nFactor == 1)
240         return aPreview.GetBitmapEx();
241     else
242     {
243         BitmapEx aScaledPreview = aPreview.GetBitmapEx();
244         aScaledPreview.Scale(
245             Size(aPreviewSize.Width,aPreviewSize.Height),
246             BMP_SCALE_INTERPOLATE);
247         return aScaledPreview;
248     }
249 }
250 
251 
252 
253 
254 void SlideRenderer::ThrowIfDisposed (void)
255     throw (::com::sun::star::lang::DisposedException)
256 {
257 	if (SlideRendererInterfaceBase::rBHelper.bDisposed || SlideRendererInterfaceBase::rBHelper.bInDispose)
258 	{
259         throw lang::DisposedException (
260             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
261                 "SlideRenderer object has already been disposed")),
262             static_cast<uno::XWeak*>(this));
263     }
264 }
265 
266 
267 } } // end of namespace ::sd::presenter
268 
269