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