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