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