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