1*25ea7f45SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*25ea7f45SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*25ea7f45SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*25ea7f45SAndrew Rist * distributed with this work for additional information 6*25ea7f45SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*25ea7f45SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*25ea7f45SAndrew Rist * "License"); you may not use this file except in compliance 9*25ea7f45SAndrew Rist * with the License. You may obtain a copy of the License at 10*25ea7f45SAndrew Rist * 11*25ea7f45SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*25ea7f45SAndrew Rist * 13*25ea7f45SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*25ea7f45SAndrew Rist * software distributed under the License is distributed on an 15*25ea7f45SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*25ea7f45SAndrew Rist * KIND, either express or implied. See the License for the 17*25ea7f45SAndrew Rist * specific language governing permissions and limitations 18*25ea7f45SAndrew Rist * under the License. 19*25ea7f45SAndrew Rist * 20*25ea7f45SAndrew Rist *************************************************************/ 21*25ea7f45SAndrew Rist 22*25ea7f45SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_canvas.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <canvas/debug.hxx> 28cdf0e10cSrcweir #include <canvas/verbosetrace.hxx> 29cdf0e10cSrcweir #include <tools/diagnose_ex.h> 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include <rtl/logfile.hxx> 32cdf0e10cSrcweir #include <rtl/math.hxx> 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <canvas/canvastools.hxx> 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 37cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 38cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx> 39cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx> 40cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx> 41cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 42cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygonrasterconverter.hxx> 43cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontriangulator.hxx> 44cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygoncutandtouch.hxx> 45cdf0e10cSrcweir 46cdf0e10cSrcweir #include "cairo_canvascustomsprite.hxx" 47cdf0e10cSrcweir #include "cairo_spritehelper.hxx" 48cdf0e10cSrcweir 49cdf0e10cSrcweir #include <memory> 50cdf0e10cSrcweir 51cdf0e10cSrcweir 52cdf0e10cSrcweir using namespace ::cairo; 53cdf0e10cSrcweir using namespace ::com::sun::star; 54cdf0e10cSrcweir 55cdf0e10cSrcweir namespace cairocanvas 56cdf0e10cSrcweir { SpriteHelper()57cdf0e10cSrcweir SpriteHelper::SpriteHelper() : 58cdf0e10cSrcweir mpSpriteCanvas(), 59cdf0e10cSrcweir mpBufferSurface(), 60cdf0e10cSrcweir mbTextureDirty(true) 61cdf0e10cSrcweir {} 62cdf0e10cSrcweir init(const geometry::RealSize2D & rSpriteSize,const SpriteCanvasRef & rSpriteCanvas)63cdf0e10cSrcweir void SpriteHelper::init( const geometry::RealSize2D& rSpriteSize, 64cdf0e10cSrcweir const SpriteCanvasRef& rSpriteCanvas ) 65cdf0e10cSrcweir { 66cdf0e10cSrcweir ENSURE_OR_THROW( rSpriteCanvas.get(), 67cdf0e10cSrcweir "SpriteHelper::init(): Invalid device, sprite canvas or surface" ); 68cdf0e10cSrcweir 69cdf0e10cSrcweir mpSpriteCanvas = rSpriteCanvas; 70cdf0e10cSrcweir mbTextureDirty = true; 71cdf0e10cSrcweir 72cdf0e10cSrcweir // also init base class 73cdf0e10cSrcweir CanvasCustomSpriteHelper::init( rSpriteSize, 74cdf0e10cSrcweir rSpriteCanvas.get() ); 75cdf0e10cSrcweir } 76cdf0e10cSrcweir setSurface(const SurfaceSharedPtr & pBufferSurface)77cdf0e10cSrcweir void SpriteHelper::setSurface( const SurfaceSharedPtr& pBufferSurface ) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir mpBufferSurface = pBufferSurface; 80cdf0e10cSrcweir } 81cdf0e10cSrcweir disposing()82cdf0e10cSrcweir void SpriteHelper::disposing() 83cdf0e10cSrcweir { 84cdf0e10cSrcweir mpBufferSurface.reset(); 85cdf0e10cSrcweir mpSpriteCanvas.clear(); 86cdf0e10cSrcweir 87cdf0e10cSrcweir // forward to parent 88cdf0e10cSrcweir CanvasCustomSpriteHelper::disposing(); 89cdf0e10cSrcweir } 90cdf0e10cSrcweir redraw(const CairoSharedPtr & pCairo,const::basegfx::B2DPoint & rPos,bool &,bool) const91cdf0e10cSrcweir void SpriteHelper::redraw( const CairoSharedPtr& pCairo, 92cdf0e10cSrcweir const ::basegfx::B2DPoint& rPos, 93cdf0e10cSrcweir bool& /*io_bSurfacesDirty*/, 94cdf0e10cSrcweir bool /*bBufferedUpdate*/ ) const 95cdf0e10cSrcweir { 96cdf0e10cSrcweir #ifdef CAIRO_CANVAS_PERF_TRACE 97cdf0e10cSrcweir struct timespec aTimer; 98cdf0e10cSrcweir mxDevice->startPerfTrace( &aTimer ); 99cdf0e10cSrcweir #endif 100cdf0e10cSrcweir 101cdf0e10cSrcweir const double fAlpha( getAlpha() ); 102cdf0e10cSrcweir const ::basegfx::B2DHomMatrix aTransform( getTransformation() ); 103cdf0e10cSrcweir 104cdf0e10cSrcweir if( isActive() && !::basegfx::fTools::equalZero( fAlpha ) ) { 105cdf0e10cSrcweir OSL_TRACE ("CanvasCustomSprite::redraw called"); 106cdf0e10cSrcweir if( pCairo ) { 107cdf0e10cSrcweir basegfx::B2DVector aSize = getSizePixel(); 108cdf0e10cSrcweir cairo_save( pCairo.get() ); 109cdf0e10cSrcweir 110cdf0e10cSrcweir double fX, fY; 111cdf0e10cSrcweir 112cdf0e10cSrcweir fX = rPos.getX(); 113cdf0e10cSrcweir fY = rPos.getY(); 114cdf0e10cSrcweir 115cdf0e10cSrcweir if( !aTransform.isIdentity() ) { 116cdf0e10cSrcweir cairo_matrix_t aMatrix, aInverseMatrix; 117cdf0e10cSrcweir cairo_matrix_init( &aMatrix, 118cdf0e10cSrcweir aTransform.get( 0, 0 ), aTransform.get( 1, 0 ), aTransform.get( 0, 1 ), 119cdf0e10cSrcweir aTransform.get( 1, 1 ), aTransform.get( 0, 2 ), aTransform.get( 1, 2 ) ); 120cdf0e10cSrcweir 121cdf0e10cSrcweir aMatrix.x0 = basegfx::fround( aMatrix.x0 ); 122cdf0e10cSrcweir aMatrix.y0 = basegfx::fround( aMatrix.y0 ); 123cdf0e10cSrcweir 124cdf0e10cSrcweir cairo_matrix_init( &aInverseMatrix, aMatrix.xx, aMatrix.yx, aMatrix.xy, aMatrix.yy, aMatrix.x0, aMatrix.y0 ); 125cdf0e10cSrcweir cairo_matrix_invert( &aInverseMatrix ); 126cdf0e10cSrcweir cairo_matrix_transform_distance( &aInverseMatrix, &fX, &fY ); 127cdf0e10cSrcweir 128cdf0e10cSrcweir cairo_set_matrix( pCairo.get(), &aMatrix ); 129cdf0e10cSrcweir } 130cdf0e10cSrcweir 131cdf0e10cSrcweir fX = basegfx::fround( fX ); 132cdf0e10cSrcweir fY = basegfx::fround( fY ); 133cdf0e10cSrcweir 134cdf0e10cSrcweir cairo_matrix_t aOrigMatrix; 135cdf0e10cSrcweir cairo_get_matrix( pCairo.get(), &aOrigMatrix ); 136cdf0e10cSrcweir cairo_translate( pCairo.get(), fX, fY ); 137cdf0e10cSrcweir 138cdf0e10cSrcweir if( getClip().is() ) 139cdf0e10cSrcweir { 140cdf0e10cSrcweir const uno::Reference<rendering::XPolyPolygon2D>& rClip( getClip() ); 141cdf0e10cSrcweir 142cdf0e10cSrcweir ::basegfx::B2DPolyPolygon aClipPoly( 143cdf0e10cSrcweir ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( 144cdf0e10cSrcweir rClip )); 145cdf0e10cSrcweir 146cdf0e10cSrcweir doPolyPolygonImplementation( aClipPoly, Clip, pCairo.get(), 147cdf0e10cSrcweir NULL, SurfaceProviderRef(mpSpriteCanvas.get()), 148cdf0e10cSrcweir rClip->getFillRule() ); 149cdf0e10cSrcweir } 150cdf0e10cSrcweir 151cdf0e10cSrcweir OSL_TRACE ("aSize %f x %f position: %f,%f", aSize.getX(), aSize.getY(), fX, fY ); 152cdf0e10cSrcweir cairo_rectangle( pCairo.get(), 0, 0, floor( aSize.getX() ), floor( aSize.getY() ) ); 153cdf0e10cSrcweir cairo_clip( pCairo.get() ); 154cdf0e10cSrcweir cairo_set_matrix( pCairo.get(), &aOrigMatrix ); 155cdf0e10cSrcweir 156cdf0e10cSrcweir if( isContentFullyOpaque() ) 157cdf0e10cSrcweir cairo_set_operator( pCairo.get(), CAIRO_OPERATOR_SOURCE ); 158cdf0e10cSrcweir cairo_set_source_surface( pCairo.get(), 159cdf0e10cSrcweir mpBufferSurface->getCairoSurface().get(), 160cdf0e10cSrcweir fX, fY ); 161cdf0e10cSrcweir if( ::rtl::math::approxEqual( fAlpha, 1.0 ) ) 162cdf0e10cSrcweir cairo_paint( pCairo.get() ); 163cdf0e10cSrcweir else 164cdf0e10cSrcweir cairo_paint_with_alpha( pCairo.get(), fAlpha ); 165cdf0e10cSrcweir 166cdf0e10cSrcweir cairo_restore( pCairo.get() ); 167cdf0e10cSrcweir } 168cdf0e10cSrcweir } 169cdf0e10cSrcweir 170cdf0e10cSrcweir #ifdef CAIRO_CANVAS_PERF_TRACE 171cdf0e10cSrcweir mxDevice->stopPerfTrace( &aTimer, "sprite redraw" ); 172cdf0e10cSrcweir #endif 173cdf0e10cSrcweir } 174cdf0e10cSrcweir polyPolygonFromXPolyPolygon2D(uno::Reference<rendering::XPolyPolygon2D> & xPoly) const175cdf0e10cSrcweir ::basegfx::B2DPolyPolygon SpriteHelper::polyPolygonFromXPolyPolygon2D( uno::Reference< rendering::XPolyPolygon2D >& xPoly ) const 176cdf0e10cSrcweir { 177cdf0e10cSrcweir return ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPoly); 178cdf0e10cSrcweir } 179cdf0e10cSrcweir } 180