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