1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cairo_spritehelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_canvas.hxx"
34 #include <canvas/debug.hxx>
35 #include <canvas/verbosetrace.hxx>
36 #include <tools/diagnose_ex.h>
38 #include <rtl/logfile.hxx>
39 #include <rtl/math.hxx>
41 #include <canvas/canvastools.hxx>
43 #include <basegfx/matrix/b2dhommatrix.hxx>
44 #include <basegfx/point/b2dpoint.hxx>
45 #include <basegfx/tools/canvastools.hxx>
46 #include <basegfx/numeric/ftools.hxx>
47 #include <basegfx/polygon/b2dpolypolygontools.hxx>
48 #include <basegfx/polygon/b2dpolygontools.hxx>
49 #include <basegfx/polygon/b2dpolypolygonrasterconverter.hxx>
50 #include <basegfx/polygon/b2dpolygontriangulator.hxx>
51 #include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
53 #include "cairo_canvascustomsprite.hxx"
54 #include "cairo_spritehelper.hxx"
59 using namespace ::cairo
;
60 using namespace ::com::sun::star
;
64 SpriteHelper::SpriteHelper() :
70 void SpriteHelper::init( const geometry::RealSize2D
& rSpriteSize
,
71 const SpriteCanvasRef
& rSpriteCanvas
)
73 ENSURE_OR_THROW( rSpriteCanvas
.get(),
74 "SpriteHelper::init(): Invalid device, sprite canvas or surface" );
76 mpSpriteCanvas
= rSpriteCanvas
;
77 mbTextureDirty
= true;
79 // also init base class
80 CanvasCustomSpriteHelper::init( rSpriteSize
,
81 rSpriteCanvas
.get() );
84 void SpriteHelper::setSurface( const SurfaceSharedPtr
& pBufferSurface
)
86 mpBufferSurface
= pBufferSurface
;
89 void SpriteHelper::disposing()
91 mpBufferSurface
.reset();
92 mpSpriteCanvas
.clear();
95 CanvasCustomSpriteHelper::disposing();
98 void SpriteHelper::redraw( const CairoSharedPtr
& pCairo
,
99 const ::basegfx::B2DPoint
& rPos
,
100 bool& /*io_bSurfacesDirty*/,
101 bool /*bBufferedUpdate*/ ) const
103 #ifdef CAIRO_CANVAS_PERF_TRACE
104 struct timespec aTimer
;
105 mxDevice
->startPerfTrace( &aTimer
);
108 const double fAlpha( getAlpha() );
109 const ::basegfx::B2DHomMatrix
aTransform( getTransformation() );
111 if( isActive() && !::basegfx::fTools::equalZero( fAlpha
) ) {
112 OSL_TRACE ("CanvasCustomSprite::redraw called");
114 basegfx::B2DVector aSize
= getSizePixel();
115 cairo_save( pCairo
.get() );
122 if( !aTransform
.isIdentity() ) {
123 cairo_matrix_t aMatrix
, aInverseMatrix
;
124 cairo_matrix_init( &aMatrix
,
125 aTransform
.get( 0, 0 ), aTransform
.get( 1, 0 ), aTransform
.get( 0, 1 ),
126 aTransform
.get( 1, 1 ), aTransform
.get( 0, 2 ), aTransform
.get( 1, 2 ) );
128 aMatrix
.x0
= basegfx::fround( aMatrix
.x0
);
129 aMatrix
.y0
= basegfx::fround( aMatrix
.y0
);
131 cairo_matrix_init( &aInverseMatrix
, aMatrix
.xx
, aMatrix
.yx
, aMatrix
.xy
, aMatrix
.yy
, aMatrix
.x0
, aMatrix
.y0
);
132 cairo_matrix_invert( &aInverseMatrix
);
133 cairo_matrix_transform_distance( &aInverseMatrix
, &fX
, &fY
);
135 cairo_set_matrix( pCairo
.get(), &aMatrix
);
138 fX
= basegfx::fround( fX
);
139 fY
= basegfx::fround( fY
);
141 cairo_matrix_t aOrigMatrix
;
142 cairo_get_matrix( pCairo
.get(), &aOrigMatrix
);
143 cairo_translate( pCairo
.get(), fX
, fY
);
147 const uno::Reference
<rendering::XPolyPolygon2D
>& rClip( getClip() );
149 ::basegfx::B2DPolyPolygon
aClipPoly(
150 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(
153 doPolyPolygonImplementation( aClipPoly
, Clip
, pCairo
.get(),
154 NULL
, SurfaceProviderRef(mpSpriteCanvas
.get()),
155 rClip
->getFillRule() );
158 OSL_TRACE ("aSize %f x %f position: %f,%f", aSize
.getX(), aSize
.getY(), fX
, fY
);
159 cairo_rectangle( pCairo
.get(), 0, 0, floor( aSize
.getX() ), floor( aSize
.getY() ) );
160 cairo_clip( pCairo
.get() );
161 cairo_set_matrix( pCairo
.get(), &aOrigMatrix
);
163 if( isContentFullyOpaque() )
164 cairo_set_operator( pCairo
.get(), CAIRO_OPERATOR_SOURCE
);
165 cairo_set_source_surface( pCairo
.get(),
166 mpBufferSurface
->getCairoSurface().get(),
168 if( ::rtl::math::approxEqual( fAlpha
, 1.0 ) )
169 cairo_paint( pCairo
.get() );
171 cairo_paint_with_alpha( pCairo
.get(), fAlpha
);
173 cairo_restore( pCairo
.get() );
177 #ifdef CAIRO_CANVAS_PERF_TRACE
178 mxDevice
->stopPerfTrace( &aTimer
, "sprite redraw" );
182 ::basegfx::B2DPolyPolygon
SpriteHelper::polyPolygonFromXPolyPolygon2D( uno::Reference
< rendering::XPolyPolygon2D
>& xPoly
) const
184 return ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPoly
);