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