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