1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_canvas.hxx" 30 31 #include <ctype.h> // don't ask. msdev breaks otherwise... 32 #include <canvas/debug.hxx> 33 #include <canvas/verbosetrace.hxx> 34 #include <tools/diagnose_ex.h> 35 36 #include <rtl/logfile.hxx> 37 #include <rtl/math.hxx> 38 39 #include <canvas/canvastools.hxx> 40 41 #include <basegfx/matrix/b2dhommatrix.hxx> 42 #include <basegfx/point/b2dpoint.hxx> 43 #include <basegfx/tools/canvastools.hxx> 44 #include <basegfx/numeric/ftools.hxx> 45 #include <basegfx/polygon/b2dpolypolygontools.hxx> 46 #include <basegfx/polygon/b2dpolygontools.hxx> 47 #include <basegfx/polygon/b2dpolypolygonrasterconverter.hxx> 48 #include <basegfx/polygon/b2dpolygontriangulator.hxx> 49 #include <basegfx/polygon/b2dpolygoncutandtouch.hxx> 50 51 #include "dx_canvascustomsprite.hxx" 52 #include "dx_spritehelper.hxx" 53 #include "dx_impltools.hxx" 54 55 #include <memory> 56 57 using namespace ::com::sun::star; 58 59 namespace dxcanvas 60 { 61 SpriteHelper::SpriteHelper() : 62 mpSpriteCanvas(), 63 mpBitmap(), 64 mbTextureDirty( true ), 65 mbShowSpriteBounds( false ) 66 { 67 } 68 69 void SpriteHelper::init( const geometry::RealSize2D& rSpriteSize, 70 const SpriteCanvasRef& rSpriteCanvas, 71 const IDXRenderModuleSharedPtr& rRenderModule, 72 const DXSurfaceBitmapSharedPtr rBitmap, 73 bool bShowSpriteBounds ) 74 { 75 ENSURE_OR_THROW( rSpriteCanvas.get() && 76 rRenderModule && 77 rBitmap, 78 "SpriteHelper::init(): Invalid device, sprite canvas or surface" ); 79 80 mpSpriteCanvas = rSpriteCanvas; 81 mpBitmap = rBitmap; 82 mbTextureDirty = true; 83 mbShowSpriteBounds = bShowSpriteBounds; 84 85 // also init base class 86 CanvasCustomSpriteHelper::init( rSpriteSize, 87 rSpriteCanvas.get() ); 88 } 89 90 void SpriteHelper::disposing() 91 { 92 mpBitmap.reset(); 93 mpSpriteCanvas.clear(); 94 95 // forward to parent 96 CanvasCustomSpriteHelper::disposing(); 97 } 98 99 ::basegfx::B2DPolyPolygon SpriteHelper::polyPolygonFromXPolyPolygon2D( uno::Reference< rendering::XPolyPolygon2D >& xPoly ) const 100 { 101 return tools::polyPolygonFromXPolyPolygon2D( xPoly ); 102 } 103 104 bool SpriteHelper::needRedraw() const 105 { 106 if( !mpBitmap || 107 !mpSpriteCanvas.get() ) 108 { 109 return false; // we're disposed, no redraw necessary 110 } 111 112 if( !isActive() || 113 ::basegfx::fTools::equalZero( getAlpha() ) ) 114 { 115 return false; // sprite is invisible 116 } 117 118 return true; 119 } 120 121 void SpriteHelper::redraw( bool& io_bSurfaceDirty ) const 122 { 123 if( !mpBitmap || 124 !mpSpriteCanvas.get() ) 125 { 126 return; // we're disposed 127 } 128 129 const ::basegfx::B2DPoint& rPos( getPosPixel() ); 130 const double fAlpha( getAlpha() ); 131 132 if( isActive() && 133 !::basegfx::fTools::equalZero( fAlpha ) ) 134 { 135 136 // TODO(Q2): For the time being, Device does not take a target 137 // surface, but always unconditionally renders to the 138 // background buffer. 139 140 // log output pos in device pixel 141 VERBOSE_TRACE( "SpriteHelper::redraw(): output pos is (%f, %f)", 142 rPos.getX(), 143 rPos.getY() ); 144 145 const double fAlpha( getAlpha() ); 146 const ::basegfx::B2DVector& rSize( getSizePixel() ); 147 const ::basegfx::B2DHomMatrix& rTransform( getTransformation() ); 148 const uno::Reference< rendering::XPolyPolygon2D >& xClip( getClip() ); 149 150 mbTextureDirty = false; 151 io_bSurfaceDirty = false; // state taken, and processed. 152 153 ::basegfx::B2DPolyPolygon aClipPath; // empty for no clip 154 bool bIsClipRectangular( false ); // false, if no 155 // clip, or clip 156 // is complex 157 158 // setup and apply clip (if any) 159 // ================================= 160 161 if( xClip.is() ) 162 { 163 aClipPath = tools::polyPolygonFromXPolyPolygon2D( xClip ); 164 165 const sal_Int32 nNumClipPolygons( aClipPath.count() ); 166 if( nNumClipPolygons ) 167 { 168 // TODO(P2): hold rectangle attribute directly 169 // at the XPolyPolygon2D 170 171 // check whether the clip is rectangular 172 if( nNumClipPolygons == 1 ) 173 if( ::basegfx::tools::isRectangle( aClipPath.getB2DPolygon( 0 ) ) ) 174 bIsClipRectangular = true; 175 } 176 } 177 178 const ::basegfx::B2DRectangle aSourceRect( 0.0, 179 0.0, 180 rSize.getX(), 181 rSize.getY() ); 182 183 // draw simple rectangular area if no clip is set. 184 if( !aClipPath.count() ) 185 { 186 mpBitmap->draw(fAlpha,rPos,rTransform); 187 } 188 else if( bIsClipRectangular ) 189 { 190 // apply a simple rect clip 191 // ======================== 192 193 ::basegfx::B2DRectangle aClipBounds( 194 ::basegfx::tools::getRange( aClipPath ) ); 195 aClipBounds.intersect( aSourceRect ); 196 197 mpBitmap->draw(fAlpha,rPos,aClipBounds,rTransform); 198 } 199 else 200 { 201 // apply clip the hard way 202 // ======================= 203 204 mpBitmap->draw(fAlpha,rPos,aClipPath,rTransform); 205 } 206 207 if( mbShowSpriteBounds ) 208 { 209 if( aClipPath.count() ) 210 { 211 // TODO(F2): Re-enable debug output 212 } 213 } 214 } 215 } 216 } 217