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