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