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_slideshow.hxx" 30 31 // must be first 32 #include <canvas/debug.hxx> 33 #include <tools/diagnose_ex.h> 34 35 #include "viewbackgroundshape.hxx" 36 #include "tools.hxx" 37 38 #include <rtl/logfile.hxx> 39 #include <rtl/math.hxx> 40 41 #include <comphelper/anytostring.hxx> 42 #include <cppuhelper/exc_hlp.hxx> 43 44 #include <basegfx/polygon/b2dpolygontools.hxx> 45 #include <basegfx/polygon/b2dpolygon.hxx> 46 #include <basegfx/numeric/ftools.hxx> 47 #include <basegfx/matrix/b2dhommatrix.hxx> 48 #include <basegfx/matrix/b2dhommatrixtools.hxx> 49 50 #include <com/sun/star/rendering/XCanvas.hpp> 51 52 #include <canvas/verbosetrace.hxx> 53 #include <canvas/canvastools.hxx> 54 #include <cppcanvas/vclfactory.hxx> 55 #include <cppcanvas/basegfxfactory.hxx> 56 #include <cppcanvas/renderer.hxx> 57 #include <cppcanvas/bitmap.hxx> 58 59 using namespace ::com::sun::star; 60 61 62 namespace slideshow 63 { 64 namespace internal 65 { 66 67 bool ViewBackgroundShape::prefetch( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 68 const GDIMetaFileSharedPtr& rMtf ) const 69 { 70 RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewBackgroundShape::prefetch()" ); 71 ENSURE_OR_RETURN_FALSE( rMtf, 72 "ViewBackgroundShape::prefetch(): no valid metafile!" ); 73 74 const ::basegfx::B2DHomMatrix& rCanvasTransform( 75 mpViewLayer->getTransformation() ); 76 77 if( !mxBitmap.is() || 78 rMtf != mpLastMtf || 79 rCanvasTransform != maLastTransformation ) 80 { 81 // buffered bitmap is invalid, re-create 82 83 // determine transformed page bounds 84 ::basegfx::B2DRectangle aTmpRect; 85 ::canvas::tools::calcTransformedRectBounds( aTmpRect, 86 maBounds, 87 rCanvasTransform ); 88 89 // determine pixel size of bitmap (choose it one pixel 90 // larger, as polygon rendering takes one pixel more 91 // to the right and to the bottom) 92 const ::basegfx::B2ISize aBmpSizePixel( 93 ::basegfx::fround( aTmpRect.getRange().getX() + 1), 94 ::basegfx::fround( aTmpRect.getRange().getY() + 1) ); 95 96 // create a bitmap of appropriate size 97 ::cppcanvas::BitmapSharedPtr pBitmap( 98 ::cppcanvas::BaseGfxFactory::getInstance().createBitmap( 99 rDestinationCanvas, 100 aBmpSizePixel ) ); 101 102 ENSURE_OR_THROW( pBitmap, 103 "ViewBackgroundShape::prefetch(): Cannot create background bitmap" ); 104 105 ::cppcanvas::BitmapCanvasSharedPtr pBitmapCanvas( pBitmap->getBitmapCanvas() ); 106 107 ENSURE_OR_THROW( pBitmapCanvas, 108 "ViewBackgroundShape::prefetch(): Cannot create background bitmap canvas" ); 109 110 // clear bitmap 111 initSlideBackground( pBitmapCanvas, 112 aBmpSizePixel ); 113 114 // apply linear part of destination canvas transformation (linear means in this context: 115 // transformation without any translational components) 116 ::basegfx::B2DHomMatrix aLinearTransform( rCanvasTransform ); 117 aLinearTransform.set( 0, 2, 0.0 ); 118 aLinearTransform.set( 1, 2, 0.0 ); 119 pBitmapCanvas->setTransformation( aLinearTransform ); 120 121 const basegfx::B2DHomMatrix aShapeTransform(basegfx::tools::createScaleTranslateB2DHomMatrix( 122 maBounds.getWidth(), maBounds.getHeight(), 123 maBounds.getMinX(), maBounds.getMinY())); 124 125 ::cppcanvas::RendererSharedPtr pRenderer( 126 ::cppcanvas::VCLFactory::getInstance().createRenderer( 127 pBitmapCanvas, 128 *rMtf.get(), 129 ::cppcanvas::Renderer::Parameters() ) ); 130 131 ENSURE_OR_RETURN_FALSE( pRenderer, 132 "ViewBackgroundShape::prefetch(): Could not create Renderer" ); 133 134 pRenderer->setTransformation( aShapeTransform ); 135 pRenderer->draw(); 136 137 mxBitmap = pBitmap->getUNOBitmap(); 138 } 139 140 mpLastMtf = rMtf; 141 maLastTransformation = rCanvasTransform; 142 143 return mxBitmap.is(); 144 } 145 146 ViewBackgroundShape::ViewBackgroundShape( const ViewLayerSharedPtr& rViewLayer, 147 const ::basegfx::B2DRectangle& rShapeBounds ) : 148 mpViewLayer( rViewLayer ), 149 mxBitmap(), 150 mpLastMtf(), 151 maLastTransformation(), 152 maBounds( rShapeBounds ) 153 { 154 ENSURE_OR_THROW( mpViewLayer, "ViewBackgroundShape::ViewBackgroundShape(): Invalid View" ); 155 ENSURE_OR_THROW( mpViewLayer->getCanvas(), "ViewBackgroundShape::ViewBackgroundShape(): Invalid ViewLayer canvas" ); 156 } 157 158 ViewLayerSharedPtr ViewBackgroundShape::getViewLayer() const 159 { 160 return mpViewLayer; 161 } 162 163 bool ViewBackgroundShape::render( const GDIMetaFileSharedPtr& rMtf ) const 164 { 165 RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewBackgroundShape::draw()" ); 166 167 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas( mpViewLayer->getCanvas() ); 168 169 if( !prefetch( rDestinationCanvas, rMtf ) ) 170 return false; 171 172 ENSURE_OR_RETURN_FALSE( mxBitmap.is(), 173 "ViewBackgroundShape::draw(): Invalid background bitmap" ); 174 175 ::basegfx::B2DHomMatrix aTransform( mpViewLayer->getTransformation() ); 176 177 // invert the linear part of the view transformation 178 // (i.e. the view transformation without translational 179 // components), to be able to leave the canvas 180 // transformation intact (would otherwise destroy possible 181 // clippings, as the clip polygon is relative to the view 182 // coordinate system). 183 aTransform.set(0,2, 0.0 ); 184 aTransform.set(1,2, 0.0 ); 185 aTransform.invert(); 186 187 rendering::RenderState aRenderState; 188 ::canvas::tools::initRenderState( aRenderState ); 189 190 ::canvas::tools::setRenderStateTransform( aRenderState, aTransform ); 191 192 try 193 { 194 rDestinationCanvas->getUNOCanvas()->drawBitmap( mxBitmap, 195 rDestinationCanvas->getViewState(), 196 aRenderState ); 197 } 198 catch( uno::Exception& ) 199 { 200 OSL_ENSURE( false, 201 rtl::OUStringToOString( 202 comphelper::anyToString( cppu::getCaughtException() ), 203 RTL_TEXTENCODING_UTF8 ).getStr() ); 204 205 return false; 206 } 207 208 return true; 209 } 210 211 } 212 } 213