Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "SlideRenderer.hxx"
21 : #include "facreg.hxx"
22 : #include "sdpage.hxx"
23 : #include <toolkit/helper/vclunohelper.hxx>
24 : #include <com/sun/star/rendering/XBitmapCanvas.hpp>
25 : #include <osl/mutex.hxx>
26 : #include <vcl/svapp.hxx>
27 : #include <cppcanvas/vclfactory.hxx>
28 : #include <cppuhelper/supportsservice.hxx>
29 :
30 : using namespace ::com::sun::star;
31 : using namespace ::com::sun::star::uno;
32 :
33 : namespace sd { namespace presenter {
34 :
35 : //===== SlideRenderer ==========================================================
36 :
37 1 : SlideRenderer::SlideRenderer (const Reference<XComponentContext>& rxContext)
38 : : SlideRendererInterfaceBase(m_aMutex),
39 1 : maPreviewRenderer()
40 : {
41 : (void)rxContext;
42 1 : }
43 :
44 2 : SlideRenderer::~SlideRenderer()
45 : {
46 2 : }
47 :
48 1 : void SAL_CALL SlideRenderer::disposing()
49 : {
50 1 : }
51 :
52 : //----- XInitialization -------------------------------------------------------
53 :
54 1 : void SAL_CALL SlideRenderer::initialize (const Sequence<Any>& rArguments)
55 : throw (Exception, RuntimeException, std::exception)
56 : {
57 1 : ThrowIfDisposed();
58 :
59 1 : if (rArguments.getLength() != 0)
60 : {
61 : throw RuntimeException("SlideRenderer: invalid number of arguments",
62 0 : static_cast<XWeak*>(this));
63 : }
64 1 : }
65 :
66 1 : OUString SlideRenderer::getImplementationName()
67 : throw (css::uno::RuntimeException, std::exception)
68 : {
69 1 : return OUString("com.sun.star.comp.Draw.SlideRenderer");
70 : }
71 :
72 0 : sal_Bool SlideRenderer::supportsService(OUString const & ServiceName)
73 : throw (css::uno::RuntimeException, std::exception)
74 : {
75 0 : return cppu::supportsService(this, ServiceName);
76 : }
77 :
78 1 : css::uno::Sequence<OUString> SlideRenderer::getSupportedServiceNames()
79 : throw (css::uno::RuntimeException, std::exception)
80 : {
81 1 : return css::uno::Sequence<OUString>{"com.sun.star.drawing.SlideRenderer"};
82 : }
83 :
84 : //----- XSlideRenderer --------------------------------------------------------
85 :
86 0 : Reference<awt::XBitmap> SlideRenderer::createPreview (
87 : const Reference<drawing::XDrawPage>& rxSlide,
88 : const awt::Size& rMaximalSize,
89 : sal_Int16 nSuperSampleFactor)
90 : throw (css::uno::RuntimeException, std::exception)
91 : {
92 0 : ThrowIfDisposed();
93 0 : SolarMutexGuard aGuard;
94 :
95 : return VCLUnoHelper::CreateBitmap(
96 0 : CreatePreview(rxSlide, rMaximalSize, nSuperSampleFactor));
97 : }
98 :
99 0 : Reference<rendering::XBitmap> SlideRenderer::createPreviewForCanvas (
100 : const Reference<drawing::XDrawPage>& rxSlide,
101 : const awt::Size& rMaximalSize,
102 : sal_Int16 nSuperSampleFactor,
103 : const Reference<rendering::XCanvas>& rxCanvas)
104 : throw (css::uno::RuntimeException, std::exception)
105 : {
106 0 : ThrowIfDisposed();
107 0 : SolarMutexGuard aGuard;
108 :
109 : cppcanvas::CanvasSharedPtr pCanvas (
110 0 : cppcanvas::VCLFactory::createCanvas(rxCanvas));
111 0 : if (pCanvas.get() != NULL)
112 : return cppcanvas::VCLFactory::createBitmap(
113 : pCanvas,
114 0 : CreatePreview(rxSlide, rMaximalSize, nSuperSampleFactor))->getUNOBitmap();
115 : else
116 0 : return NULL;
117 : }
118 :
119 0 : awt::Size SAL_CALL SlideRenderer::calculatePreviewSize (
120 : double nSlideAspectRatio,
121 : const awt::Size& rMaximalSize)
122 : throw (css::uno::RuntimeException, std::exception)
123 : {
124 0 : if (rMaximalSize.Width <= 0
125 0 : || rMaximalSize.Height <= 0
126 0 : || nSlideAspectRatio <= 0)
127 : {
128 0 : return awt::Size(0,0);
129 : }
130 :
131 0 : const double nWindowAspectRatio (double(rMaximalSize.Width) / double(rMaximalSize.Height));
132 0 : if (nSlideAspectRatio < nWindowAspectRatio)
133 : return awt::Size(
134 0 : sal::static_int_cast<sal_Int32>(rMaximalSize.Height * nSlideAspectRatio),
135 0 : rMaximalSize.Height);
136 : else
137 : return awt::Size(
138 : rMaximalSize.Width,
139 0 : sal::static_int_cast<sal_Int32>(rMaximalSize.Width / nSlideAspectRatio));
140 : }
141 :
142 0 : BitmapEx SlideRenderer::CreatePreview (
143 : const Reference<drawing::XDrawPage>& rxSlide,
144 : const awt::Size& rMaximalSize,
145 : sal_Int16 nSuperSampleFactor)
146 : throw (css::uno::RuntimeException,
147 : std::exception)
148 : {
149 0 : const SdPage* pPage = SdPage::getImplementation(rxSlide);
150 0 : if (pPage == NULL)
151 : throw lang::IllegalArgumentException("SlideRenderer::createPreview() called with invalid slide",
152 : static_cast<XWeak*>(this),
153 0 : 0);
154 :
155 : // Determine the size of the current slide and its aspect ratio.
156 0 : Size aPageSize = pPage->GetSize();
157 0 : if (aPageSize.Height() <= 0)
158 : throw lang::IllegalArgumentException("SlideRenderer::createPreview() called with invalid size",
159 : static_cast<XWeak*>(this),
160 0 : 1);
161 :
162 : // Compare with the aspect ratio of the window (which rMaximalSize
163 : // assumed to be) and calculate the size of the preview so that it
164 : // a) will have the aspect ratio of the page and
165 : // b) will be as large as possible.
166 : awt::Size aPreviewSize (calculatePreviewSize(
167 0 : double(aPageSize.Width()) / double(aPageSize.Height()),
168 0 : rMaximalSize));
169 0 : if (aPreviewSize.Width <= 0 || aPreviewSize.Height <= 0)
170 0 : return BitmapEx();
171 :
172 : // Make sure that the super sample factor has a sane value.
173 0 : sal_Int16 nFactor (nSuperSampleFactor);
174 0 : if (nFactor < 1)
175 0 : nFactor = 1;
176 0 : else if (nFactor > 10)
177 0 : nFactor = 10;
178 :
179 : // Create the preview. When the super sample factor n is greater than 1
180 : // then a preview is created in size (n*width, n*height) and then scaled
181 : // down to (width, height). This is a poor mans antialiasing for the
182 : // time being. When we have true antialiasing support this workaround
183 : // can be removed.
184 : const Image aPreview = maPreviewRenderer.RenderPage (
185 : pPage,
186 0 : Size(aPreviewSize.Width*nFactor, aPreviewSize.Height*nFactor),
187 0 : OUString());
188 0 : if (nFactor == 1)
189 0 : return aPreview.GetBitmapEx();
190 : else
191 : {
192 0 : BitmapEx aScaledPreview = aPreview.GetBitmapEx();
193 : aScaledPreview.Scale(
194 : Size(aPreviewSize.Width,aPreviewSize.Height),
195 0 : BmpScaleFlag::BestQuality);
196 0 : return aScaledPreview;
197 0 : }
198 : }
199 :
200 1 : void SlideRenderer::ThrowIfDisposed()
201 : throw (::com::sun::star::lang::DisposedException)
202 : {
203 1 : if (SlideRendererInterfaceBase::rBHelper.bDisposed || SlideRendererInterfaceBase::rBHelper.bInDispose)
204 : {
205 : throw lang::DisposedException ("SlideRenderer object has already been disposed",
206 0 : static_cast<uno::XWeak*>(this));
207 : }
208 1 : }
209 :
210 : } } // end of namespace ::sd::presenter
211 :
212 :
213 : extern "C" SAL_DLLPUBLIC_EXPORT ::com::sun::star::uno::XInterface* SAL_CALL
214 1 : com_sun_star_comp_Draw_SlideRenderer_get_implementation(::com::sun::star::uno::XComponentContext* context,
215 : ::com::sun::star::uno::Sequence<css::uno::Any> const &)
216 : {
217 1 : return cppu::acquire(new sd::presenter::SlideRenderer(context));
218 66 : }
219 :
220 :
221 :
222 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|