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 <canvas/debug.hxx> 32 #include <canvas/verbosetrace.hxx> 33 #include <canvas/canvastools.hxx> 34 35 #include <osl/mutex.hxx> 36 #include <cppuhelper/compbase1.hxx> 37 38 #include <com/sun/star/lang/NoSupportException.hpp> 39 40 #include <toolkit/helper/vclunohelper.hxx> 41 #include <basegfx/tools/canvastools.hxx> 42 #include <basegfx/tools/unopolypolygon.hxx> 43 44 #include <vcl/canvastools.hxx> 45 46 #include <tools/stream.hxx> 47 48 #include "cairo_spritecanvas.hxx" 49 #include "cairo_canvasbitmap.hxx" 50 #include "cairo_devicehelper.hxx" 51 52 using namespace ::cairo; 53 using namespace ::com::sun::star; 54 55 namespace cairocanvas 56 { 57 DeviceHelper::DeviceHelper() : 58 mpSurfaceProvider( NULL ), 59 mpRefDevice( NULL ), 60 mpSurface() 61 { 62 } 63 64 void DeviceHelper::implInit( SurfaceProvider& rSurfaceProvider, 65 OutputDevice& rRefDevice ) 66 { 67 mpSurfaceProvider = &rSurfaceProvider; 68 mpRefDevice = &rRefDevice; 69 70 // no own surface, this is handled by derived classes 71 } 72 73 void DeviceHelper::init( SurfaceProvider& rSurfaceProvider, 74 OutputDevice& rRefDevice ) 75 { 76 implInit(rSurfaceProvider, rRefDevice); 77 78 OutputDevice* pOutDev=getOutputDevice(); 79 mpSurface = cairo::createSurface( *pOutDev, 80 pOutDev->GetOutOffXPixel(), 81 pOutDev->GetOutOffYPixel(), 82 pOutDev->GetOutputWidthPixel(), 83 pOutDev->GetOutputHeightPixel() ); 84 } 85 86 void DeviceHelper::disposing() 87 { 88 // release all references 89 mpSurface.reset(); 90 mpRefDevice = NULL; 91 mpSurfaceProvider = NULL; 92 } 93 94 void DeviceHelper::setSize( const ::basegfx::B2ISize& rSize ) 95 { 96 OSL_TRACE("DeviceHelper::setSize(): device size %d x %d", rSize.getX(), rSize.getY() ); 97 98 if( !mpRefDevice ) 99 return; // disposed 100 101 OutputDevice* pOutDev=getOutputDevice(); 102 103 #if defined (UNX) && !defined (QUARTZ) 104 // X11 only 105 if( mpSurface ) 106 mpSurface->Resize( rSize.getX() + pOutDev->GetOutOffXPixel(), 107 rSize.getY() + pOutDev->GetOutOffYPixel() ); 108 else 109 #endif 110 mpSurface = cairo::createSurface( 111 *pOutDev, 112 pOutDev->GetOutOffXPixel(), 113 pOutDev->GetOutOffYPixel(), 114 rSize.getX(), rSize.getY() ); 115 } 116 117 geometry::RealSize2D DeviceHelper::getPhysicalResolution() 118 { 119 // Map a one-by-one millimeter box to pixel 120 const MapMode aOldMapMode( mpRefDevice->GetMapMode() ); 121 mpRefDevice->SetMapMode( MapMode(MAP_MM) ); 122 const Size aPixelSize( mpRefDevice->LogicToPixel(Size(1,1)) ); 123 mpRefDevice->SetMapMode( aOldMapMode ); 124 125 return ::vcl::unotools::size2DFromSize( aPixelSize ); 126 } 127 128 geometry::RealSize2D DeviceHelper::getPhysicalSize() 129 { 130 if( !mpRefDevice ) 131 return ::canvas::tools::createInfiniteSize2D(); // we're disposed 132 133 // Map the pixel dimensions of the output window to millimeter 134 const MapMode aOldMapMode( mpRefDevice->GetMapMode() ); 135 mpRefDevice->SetMapMode( MapMode(MAP_MM) ); 136 const Size aLogSize( mpRefDevice->PixelToLogic(mpRefDevice->GetOutputSizePixel()) ); 137 mpRefDevice->SetMapMode( aOldMapMode ); 138 139 return ::vcl::unotools::size2DFromSize( aLogSize ); 140 } 141 142 uno::Reference< rendering::XLinePolyPolygon2D > DeviceHelper::createCompatibleLinePolyPolygon( 143 const uno::Reference< rendering::XGraphicDevice >& , 144 const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >& points ) 145 { 146 // disposed? 147 if( !mpSurfaceProvider ) 148 return uno::Reference< rendering::XLinePolyPolygon2D >(); // we're disposed 149 150 return uno::Reference< rendering::XLinePolyPolygon2D >( 151 new ::basegfx::unotools::UnoPolyPolygon( 152 ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence( points ) ) ); 153 } 154 155 uno::Reference< rendering::XBezierPolyPolygon2D > DeviceHelper::createCompatibleBezierPolyPolygon( 156 const uno::Reference< rendering::XGraphicDevice >& , 157 const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >& points ) 158 { 159 // disposed? 160 if( !mpSurfaceProvider ) 161 return uno::Reference< rendering::XBezierPolyPolygon2D >(); // we're disposed 162 163 return uno::Reference< rendering::XBezierPolyPolygon2D >( 164 new ::basegfx::unotools::UnoPolyPolygon( 165 ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence( points ) ) ); 166 } 167 168 uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleBitmap( 169 const uno::Reference< rendering::XGraphicDevice >& rDevice, 170 const geometry::IntegerSize2D& size ) 171 { 172 // disposed? 173 if( !mpSurfaceProvider ) 174 return uno::Reference< rendering::XBitmap >(); // we're disposed 175 176 return uno::Reference< rendering::XBitmap >( 177 new CanvasBitmap( 178 ::basegfx::unotools::b2ISizeFromIntegerSize2D( size ), 179 SurfaceProviderRef(mpSurfaceProvider), 180 rDevice.get(), 181 false )); 182 } 183 184 uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileBitmap( 185 const uno::Reference< rendering::XGraphicDevice >& , 186 const geometry::IntegerSize2D& /*size*/ ) 187 { 188 return uno::Reference< rendering::XVolatileBitmap >(); 189 } 190 191 uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleAlphaBitmap( 192 const uno::Reference< rendering::XGraphicDevice >& rDevice, 193 const geometry::IntegerSize2D& size ) 194 { 195 // disposed? 196 if( !mpSurfaceProvider ) 197 return uno::Reference< rendering::XBitmap >(); // we're disposed 198 199 return uno::Reference< rendering::XBitmap >( 200 new CanvasBitmap( 201 ::basegfx::unotools::b2ISizeFromIntegerSize2D( size ), 202 SurfaceProviderRef(mpSurfaceProvider), 203 rDevice.get(), 204 true )); 205 } 206 207 uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileAlphaBitmap( 208 const uno::Reference< rendering::XGraphicDevice >& , 209 const geometry::IntegerSize2D& /*size*/ ) 210 { 211 return uno::Reference< rendering::XVolatileBitmap >(); 212 } 213 214 sal_Bool DeviceHelper::hasFullScreenMode() 215 { 216 // TODO(F3): offer fullscreen mode the XCanvas way 217 return false; 218 } 219 220 sal_Bool DeviceHelper::enterFullScreenMode( sal_Bool /*bEnter*/ ) 221 { 222 // TODO(F3): offer fullscreen mode the XCanvas way 223 return false; 224 } 225 226 uno::Any DeviceHelper::isAccelerated() const 227 { 228 return ::com::sun::star::uno::makeAny(false); 229 } 230 231 uno::Any DeviceHelper::getDeviceHandle() const 232 { 233 return uno::makeAny( reinterpret_cast< sal_Int64 >(mpRefDevice) ); 234 } 235 236 uno::Any DeviceHelper::getSurfaceHandle() const 237 { 238 return uno::Any(); 239 } 240 241 namespace 242 { 243 struct DeviceColorSpace: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>, 244 DeviceColorSpace> 245 { 246 uno::Reference<rendering::XColorSpace> operator()() 247 { 248 return vcl::unotools::createStandardColorSpace(); 249 } 250 }; 251 } 252 253 uno::Reference<rendering::XColorSpace> DeviceHelper::getColorSpace() const 254 { 255 // always the same 256 return DeviceColorSpace::get(); 257 } 258 259 void DeviceHelper::dumpScreenContent() const 260 { 261 static sal_uInt32 nFilePostfixCount(0); 262 263 if( mpRefDevice ) 264 { 265 String aFilename( String::CreateFromAscii("dbg_frontbuffer") ); 266 aFilename += String::CreateFromInt32(nFilePostfixCount); 267 aFilename += String::CreateFromAscii(".bmp"); 268 269 SvFileStream aStream( aFilename, STREAM_STD_READWRITE ); 270 271 const ::Point aEmptyPoint; 272 bool bOldMap( mpRefDevice->IsMapModeEnabled() ); 273 mpRefDevice->EnableMapMode( sal_False ); 274 aStream << mpRefDevice->GetBitmap(aEmptyPoint, 275 mpRefDevice->GetOutputSizePixel()); 276 mpRefDevice->EnableMapMode( bOldMap ); 277 278 ++nFilePostfixCount; 279 } 280 } 281 282 SurfaceSharedPtr DeviceHelper::getSurface() 283 { 284 return mpSurface; 285 } 286 287 SurfaceSharedPtr DeviceHelper::createSurface( const ::basegfx::B2ISize& rSize, Content aContent ) 288 { 289 if( mpSurface ) 290 return mpSurface->getSimilar( aContent, rSize.getX(), rSize.getY() ); 291 292 return SurfaceSharedPtr(); 293 } 294 295 SurfaceSharedPtr DeviceHelper::createSurface( BitmapSystemData& rData, const Size& rSize ) 296 { 297 if( mpRefDevice ) 298 return createBitmapSurface( *mpRefDevice, rData, rSize ); 299 300 return SurfaceSharedPtr(); 301 } 302 } 303