fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / canvas / source / directx / dx_canvasbitmap.cxx
blob64eb81d73e036ace24169fa414d573d901701c31
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <ctype.h> // don't ask. msdev breaks otherwise...
22 #include <canvas/debug.hxx>
23 #include <canvas/canvastools.hxx>
24 #include <tools/diagnose_ex.h>
26 #include <vcl/bitmapex.hxx>
28 #include <boost/preprocessor/repetition.hpp>
29 #include <boost/preprocessor/iteration/local.hpp>
30 #include <boost/scoped_array.hpp>
32 #include "dx_canvasbitmap.hxx"
33 #include "dx_impltools.hxx"
36 using namespace ::com::sun::star;
38 namespace dxcanvas
40 CanvasBitmap::CanvasBitmap( const IBitmapSharedPtr& rBitmap,
41 const DeviceRef& rDevice ) :
42 mpDevice( rDevice ),
43 mpBitmap( rBitmap )
45 ENSURE_OR_THROW( mpDevice.is() && mpBitmap,
46 "CanvasBitmap::CanvasBitmap(): Invalid surface or device" );
48 maCanvasHelper.setDevice( *mpDevice.get() );
49 maCanvasHelper.setTarget( mpBitmap );
52 void CanvasBitmap::disposeThis()
54 mpBitmap.reset();
55 mpDevice.clear();
57 // forward to parent
58 CanvasBitmap_Base::disposeThis();
61 struct AlphaDIB
63 BITMAPINFOHEADER bmiHeader;
64 RGBQUAD bmiColors[256];
67 uno::Any SAL_CALL CanvasBitmap::getFastPropertyValue( sal_Int32 nHandle ) throw (uno::RuntimeException)
69 uno::Any aRes;
70 // 0 ... get BitmapEx
71 // 1 ... get Pixbuf with bitmap RGB content
72 // 2 ... get Pixbuf with bitmap alpha mask
73 switch( nHandle )
75 // sorry, no BitmapEx here...
76 case 0:
77 aRes = ::com::sun::star::uno::Any( reinterpret_cast<sal_Int64>( (BitmapEx*) NULL ) );
78 break;
80 case 1:
82 if(!mpBitmap->hasAlpha())
84 HBITMAP aHBmp;
85 mpBitmap->getBitmap()->GetHBITMAP(Gdiplus::Color(), &aHBmp );
87 uno::Sequence< uno::Any > args(1);
88 args[0] = uno::Any( sal_Int64(aHBmp) );
90 aRes <<= args;
92 else
94 // need to copy&convert the bitmap, since dx
95 // canvas uses inline alpha channel
96 HDC hScreenDC=GetDC(NULL);
97 const basegfx::B2IVector aSize(mpBitmap->getSize());
98 HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC,
99 aSize.getX(),
100 aSize.getY() );
101 if( !hBmpBitmap )
102 return aRes;
104 BITMAPINFOHEADER aBIH;
106 aBIH.biSize = sizeof( BITMAPINFOHEADER );
107 aBIH.biWidth = aSize.getX();
108 aBIH.biHeight = -aSize.getY();
109 aBIH.biPlanes = 1;
110 aBIH.biBitCount = 32;
111 aBIH.biCompression = BI_RGB; // expects pixel in
112 // bbggrrxx format
113 // (little endian)
114 aBIH.biSizeImage = 0;
115 aBIH.biXPelsPerMeter = 0;
116 aBIH.biYPelsPerMeter = 0;
117 aBIH.biClrUsed = 0;
118 aBIH.biClrImportant = 0;
120 Gdiplus::BitmapData aBmpData;
121 aBmpData.Width = aSize.getX();
122 aBmpData.Height = aSize.getY();
123 aBmpData.Stride = 4*aBmpData.Width;
124 aBmpData.PixelFormat = PixelFormat32bppARGB;
125 aBmpData.Scan0 = NULL;
126 const Gdiplus::Rect aRect( 0,0,aSize.getX(),aSize.getY() );
127 BitmapSharedPtr pGDIPlusBitmap=mpBitmap->getBitmap();
128 if( Gdiplus::Ok != pGDIPlusBitmap->LockBits( &aRect,
129 Gdiplus::ImageLockModeRead,
130 PixelFormat32bppARGB, // outputs ARGB (big endian)
131 &aBmpData ) )
133 // failed to lock, bail out
134 return aRes;
137 // now aBmpData.Scan0 contains our bits - push
138 // them into HBITMAP, ignoring alpha
139 SetDIBits( hScreenDC, hBmpBitmap, 0, aSize.getY(), aBmpData.Scan0, (PBITMAPINFO)&aBIH, DIB_RGB_COLORS );
141 pGDIPlusBitmap->UnlockBits( &aBmpData );
143 uno::Sequence< uno::Any > args(1);
144 args[0] = uno::Any( sal_Int64(hBmpBitmap) );
146 aRes <<= args;
149 break;
151 case 2:
153 if(!mpBitmap->hasAlpha())
155 return aRes;
157 else
159 static AlphaDIB aDIB=
161 {0,0,0,1,8,BI_RGB,0,0,0,0,0},
163 // this here fills palette with grey
164 // level colors, starting from 0,0,0
165 // up to 255,255,255
166 #define BOOST_PP_LOCAL_MACRO(n_) \
167 BOOST_PP_COMMA_IF(n_) \
168 {n_,n_,n_,n_}
169 #define BOOST_PP_LOCAL_LIMITS (0, 255)
170 #include BOOST_PP_LOCAL_ITERATE()
174 // need to copy&convert the bitmap, since dx
175 // canvas uses inline alpha channel
176 HDC hScreenDC=GetDC(NULL);
177 const basegfx::B2IVector aSize(mpBitmap->getSize());
178 HBITMAP hBmpBitmap = CreateCompatibleBitmap( hScreenDC, aSize.getX(), aSize.getY() );
179 if( !hBmpBitmap )
180 return aRes;
182 aDIB.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
183 aDIB.bmiHeader.biWidth = aSize.getX();
184 aDIB.bmiHeader.biHeight = -aSize.getY();
185 aDIB.bmiHeader.biPlanes = 1;
186 aDIB.bmiHeader.biBitCount = 8;
187 aDIB.bmiHeader.biCompression = BI_RGB;
188 aDIB.bmiHeader.biSizeImage = 0;
189 aDIB.bmiHeader.biXPelsPerMeter = 0;
190 aDIB.bmiHeader.biYPelsPerMeter = 0;
191 aDIB.bmiHeader.biClrUsed = 0;
192 aDIB.bmiHeader.biClrImportant = 0;
194 Gdiplus::BitmapData aBmpData;
195 aBmpData.Width = aSize.getX();
196 aBmpData.Height = aSize.getY();
197 aBmpData.Stride = 4*aBmpData.Width;
198 aBmpData.PixelFormat = PixelFormat32bppARGB;
199 aBmpData.Scan0 = NULL;
200 const Gdiplus::Rect aRect( 0,0,aSize.getX(),aSize.getY() );
201 BitmapSharedPtr pGDIPlusBitmap=mpBitmap->getBitmap();
202 if( Gdiplus::Ok != pGDIPlusBitmap->LockBits( &aRect,
203 Gdiplus::ImageLockModeRead,
204 PixelFormat32bppARGB, // outputs ARGB (big endian)
205 &aBmpData ) )
207 // failed to lock, bail out
208 return aRes;
211 // copy only alpha channel to pAlphaBits
212 const sal_Int32 nScanWidth((aSize.getX() + 3) & ~3);
213 boost::scoped_array<sal_uInt8> pAlphaBits( new sal_uInt8[nScanWidth*aSize.getY()] );
214 const sal_uInt8* pInBits=(sal_uInt8*)aBmpData.Scan0;
215 pInBits+=3;
216 sal_uInt8* pOutBits;
217 for( sal_Int32 y=0; y<aSize.getY(); ++y )
219 pOutBits=pAlphaBits.get()+y*nScanWidth;
220 for( sal_Int32 x=0; x<aSize.getX(); ++x )
222 *pOutBits++ = 255-*pInBits;
223 pInBits += 4;
227 pGDIPlusBitmap->UnlockBits( &aBmpData );
229 // set bits to newly create HBITMAP
230 SetDIBits( hScreenDC, hBmpBitmap, 0,
231 aSize.getY(), pAlphaBits.get(),
232 (PBITMAPINFO)&aDIB, DIB_RGB_COLORS );
234 uno::Sequence< uno::Any > args(1);
235 args[0] = uno::Any( sal_Int64(hBmpBitmap) );
237 aRes <<= args;
240 break;
243 return aRes;
246 #define IMPLEMENTATION_NAME "DXCanvas.CanvasBitmap"
247 #define SERVICE_NAME "com.sun.star.rendering.CanvasBitmap"
249 OUString SAL_CALL CanvasBitmap::getImplementationName( ) throw (uno::RuntimeException)
251 return OUString( IMPLEMENTATION_NAME );
254 sal_Bool SAL_CALL CanvasBitmap::supportsService( const OUString& ServiceName ) throw (uno::RuntimeException)
256 return ServiceName == SERVICE_NAME;
259 uno::Sequence< OUString > SAL_CALL CanvasBitmap::getSupportedServiceNames( ) throw (uno::RuntimeException)
261 uno::Sequence< OUString > aRet(1);
262 aRet[0] = SERVICE_NAME;
264 return aRet;
269 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */