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 <vcl/canvastools.hxx>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <vcl/bitmap.hxx>
30cdf0e10cSrcweir #include <vcl/bitmapex.hxx>
31cdf0e10cSrcweir #include <vcl/bmpacc.hxx>
32cdf0e10cSrcweir #include <tools/diagnose_ex.h>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "dx_impltools.hxx"
35cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <canvas/debug.hxx>
38cdf0e10cSrcweir #include <canvas/verbosetrace.hxx>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
41cdf0e10cSrcweir #include <com/sun/star/rendering/XIntegerBitmap.hpp>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include <boost/scoped_array.hpp>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include "dx_vcltools.hxx"
46cdf0e10cSrcweir 
47cdf0e10cSrcweir using namespace ::com::sun::star;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir namespace dxcanvas
50cdf0e10cSrcweir {
51cdf0e10cSrcweir     namespace tools
52cdf0e10cSrcweir     {
53cdf0e10cSrcweir         namespace
54cdf0e10cSrcweir         {
55cdf0e10cSrcweir             /// Calc number of colors in given BitmapInfoHeader
calcDIBColorCount(const BITMAPINFOHEADER & rBIH)56cdf0e10cSrcweir 			sal_Int32 calcDIBColorCount( const BITMAPINFOHEADER& rBIH )
57cdf0e10cSrcweir             {
58cdf0e10cSrcweir                 if( rBIH.biSize != sizeof( BITMAPCOREHEADER ) )
59cdf0e10cSrcweir                 {
60cdf0e10cSrcweir                     if( rBIH.biBitCount <= 8 )
61cdf0e10cSrcweir                     {
62cdf0e10cSrcweir                         if( rBIH.biClrUsed )
63cdf0e10cSrcweir                             return rBIH.biClrUsed;
64cdf0e10cSrcweir                         else
65cdf0e10cSrcweir                             return 1L << rBIH.biBitCount;
66cdf0e10cSrcweir                     }
67cdf0e10cSrcweir                 }
68cdf0e10cSrcweir                 else
69cdf0e10cSrcweir                 {
70cdf0e10cSrcweir                     BITMAPCOREHEADER* pCoreHeader = (BITMAPCOREHEADER*)&rBIH;
71cdf0e10cSrcweir 
72cdf0e10cSrcweir                     if( pCoreHeader->bcBitCount <= 8 )
73cdf0e10cSrcweir                         return 1L << pCoreHeader->bcBitCount;
74cdf0e10cSrcweir                 }
75cdf0e10cSrcweir 
76cdf0e10cSrcweir                 return 0; // nothing known
77cdf0e10cSrcweir             }
78cdf0e10cSrcweir 
79cdf0e10cSrcweir             /// Draw DI bits to given Graphics
drawDIBits(const::boost::shared_ptr<Gdiplus::Graphics> & rGraphics,const void * hDIB)80cdf0e10cSrcweir             bool drawDIBits( const ::boost::shared_ptr< Gdiplus::Graphics >& rGraphics,
81cdf0e10cSrcweir                              const void* 									 hDIB )
82cdf0e10cSrcweir             {
83cdf0e10cSrcweir                 bool 			bRet( false );
84cdf0e10cSrcweir                 BitmapSharedPtr pBitmap;
85cdf0e10cSrcweir 
86cdf0e10cSrcweir                 const BITMAPINFO* pBI = (BITMAPINFO*)GlobalLock( (HGLOBAL)hDIB );
87cdf0e10cSrcweir 
88cdf0e10cSrcweir                 if( pBI )
89cdf0e10cSrcweir                 {
90cdf0e10cSrcweir                     const BITMAPINFOHEADER*	pBIH = (BITMAPINFOHEADER*)pBI;
91cdf0e10cSrcweir                     const BYTE*				pBits = (BYTE*) pBI + *(DWORD*)pBI +
92cdf0e10cSrcweir                         calcDIBColorCount( *pBIH ) * sizeof( RGBQUAD );
93cdf0e10cSrcweir 
94cdf0e10cSrcweir                     // forward to outsourced GDI+ rendering method
95cdf0e10cSrcweir                     // (header clashes)
96cdf0e10cSrcweir                     bRet = tools::drawDIBits( rGraphics, *pBI, (void*)pBits );
97cdf0e10cSrcweir 
98cdf0e10cSrcweir                     GlobalUnlock( (HGLOBAL)hDIB );
99cdf0e10cSrcweir                 }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir                 return bRet;
102cdf0e10cSrcweir             }
103cdf0e10cSrcweir 
104cdf0e10cSrcweir             /** Draw VCL bitmap to given Graphics
105cdf0e10cSrcweir 
106cdf0e10cSrcweir             	@param rBmp
107cdf0e10cSrcweir                 Reference to bitmap. Might get modified, in such a way
108cdf0e10cSrcweir                 that it will hold a DIB after a successful function call.
109cdf0e10cSrcweir              */
drawVCLBitmap(const::boost::shared_ptr<Gdiplus::Graphics> & rGraphics,::Bitmap & rBmp)110cdf0e10cSrcweir             bool drawVCLBitmap( const ::boost::shared_ptr< Gdiplus::Graphics >&	rGraphics,
111cdf0e10cSrcweir                                 ::Bitmap& 										rBmp )
112cdf0e10cSrcweir             {
113cdf0e10cSrcweir                 BitmapSystemData aBmpSysData;
114cdf0e10cSrcweir 
115cdf0e10cSrcweir                 if( !rBmp.GetSystemData( aBmpSysData ) ||
116cdf0e10cSrcweir                     !aBmpSysData.pDIB )
117cdf0e10cSrcweir                 {
118cdf0e10cSrcweir                     // first of all, ensure that Bitmap contains a DIB, by
119cdf0e10cSrcweir                     // aquiring a read access
120cdf0e10cSrcweir                     BitmapReadAccess* pReadAcc = rBmp.AcquireReadAccess();
121cdf0e10cSrcweir 
122cdf0e10cSrcweir                     // TODO(P2): Acquiring a read access can actually
123cdf0e10cSrcweir                     // force a read from VRAM, thus, avoiding this
124cdf0e10cSrcweir                     // step somehow will increase performance
125cdf0e10cSrcweir                     // here.
126cdf0e10cSrcweir                     if( pReadAcc )
127cdf0e10cSrcweir                     {
128cdf0e10cSrcweir                         // try again: now, WinSalBitmap must have
129cdf0e10cSrcweir                         // generated a DIB
130cdf0e10cSrcweir                         if( rBmp.GetSystemData( aBmpSysData ) &&
131cdf0e10cSrcweir                             aBmpSysData.pDIB )
132cdf0e10cSrcweir                         {
133cdf0e10cSrcweir                             return drawDIBits( rGraphics,
134cdf0e10cSrcweir                                                aBmpSysData.pDIB );
135cdf0e10cSrcweir                         }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir                         rBmp.ReleaseAccess( pReadAcc );
138cdf0e10cSrcweir                     }
139cdf0e10cSrcweir                 }
140cdf0e10cSrcweir                 else
141cdf0e10cSrcweir                 {
142cdf0e10cSrcweir                     return drawDIBits( rGraphics,
143cdf0e10cSrcweir                                        aBmpSysData.pDIB );
144cdf0e10cSrcweir                 }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir                 // failed to generate DIBits from vcl bitmap
147cdf0e10cSrcweir                 return false;
148cdf0e10cSrcweir             }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir             /** Create a chunk of raw RGBA data GDI+ Bitmap from VCL BbitmapEX
151cdf0e10cSrcweir              */
bitmapFromVCLBitmapEx(const::BitmapEx & rBmpEx)152cdf0e10cSrcweir             RawRGBABitmap bitmapFromVCLBitmapEx( const ::BitmapEx& rBmpEx )
153cdf0e10cSrcweir             {
154cdf0e10cSrcweir                 // TODO(P2): Avoid temporary bitmap generation, maybe
155cdf0e10cSrcweir                 // even ensure that created DIBs are copied back to
156cdf0e10cSrcweir                 // BmpEx (currently, every AcquireReadAccess() will
157cdf0e10cSrcweir                 // make the local bitmap copy unique, effectively
158cdf0e10cSrcweir                 // duplicating the memory used)
159cdf0e10cSrcweir 
160cdf0e10cSrcweir                 ENSURE_OR_THROW( rBmpEx.IsTransparent(),
161cdf0e10cSrcweir                                   "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
162cdf0e10cSrcweir                                   "BmpEx not transparent" );
163cdf0e10cSrcweir 
164cdf0e10cSrcweir                 // convert transparent bitmap to 32bit RGBA
165cdf0e10cSrcweir                 // ========================================
166cdf0e10cSrcweir 
167cdf0e10cSrcweir                 const ::Size aBmpSize( rBmpEx.GetSizePixel() );
168cdf0e10cSrcweir 
169cdf0e10cSrcweir                 RawRGBABitmap aBmpData;
170cdf0e10cSrcweir                 aBmpData.mnWidth	 = aBmpSize.Width();
171cdf0e10cSrcweir                 aBmpData.mnHeight	 = aBmpSize.Height();
172cdf0e10cSrcweir                 aBmpData.mpBitmapData.reset( new sal_uInt8[ 4*aBmpData.mnWidth*aBmpData.mnHeight ] );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir                 Bitmap aBitmap( rBmpEx.GetBitmap() );
175cdf0e10cSrcweir 
176cdf0e10cSrcweir                 ScopedBitmapReadAccess pReadAccess( aBitmap.AcquireReadAccess(),
177cdf0e10cSrcweir                                                     aBitmap );
178cdf0e10cSrcweir 
179cdf0e10cSrcweir                 const sal_Int32 nWidth( aBmpSize.Width() );
180cdf0e10cSrcweir                 const sal_Int32 nHeight( aBmpSize.Height() );
181cdf0e10cSrcweir 
182cdf0e10cSrcweir                 ENSURE_OR_THROW( pReadAccess.get() != NULL,
183cdf0e10cSrcweir                                   "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
184cdf0e10cSrcweir                                   "Unable to acquire read acces to bitmap" );
185cdf0e10cSrcweir 
186cdf0e10cSrcweir                 if( rBmpEx.IsAlpha() )
187cdf0e10cSrcweir                 {
188cdf0e10cSrcweir                     Bitmap aAlpha( rBmpEx.GetAlpha().GetBitmap() );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir                     ScopedBitmapReadAccess pAlphaReadAccess( aAlpha.AcquireReadAccess(),
191cdf0e10cSrcweir                                                              aAlpha );
192cdf0e10cSrcweir 
193cdf0e10cSrcweir                     // By convention, the access buffer always has
194cdf0e10cSrcweir                     // one of the following formats:
195cdf0e10cSrcweir                     //
196cdf0e10cSrcweir                     //    BMP_FORMAT_1BIT_MSB_PAL
197cdf0e10cSrcweir                     //	  BMP_FORMAT_4BIT_MSN_PAL
198cdf0e10cSrcweir                     //	  BMP_FORMAT_8BIT_PAL
199cdf0e10cSrcweir                     //	  BMP_FORMAT_16BIT_TC_LSB_MASK
200cdf0e10cSrcweir                     //	  BMP_FORMAT_24BIT_TC_BGR
201cdf0e10cSrcweir                     //	  BMP_FORMAT_32BIT_TC_MASK
202cdf0e10cSrcweir                     //
203cdf0e10cSrcweir                     // and is always BMP_FORMAT_BOTTOM_UP
204cdf0e10cSrcweir                     //
205cdf0e10cSrcweir                     // This is the way
206cdf0e10cSrcweir                     // WinSalBitmap::AcquireBuffer() sets up the
207cdf0e10cSrcweir                     // buffer
208cdf0e10cSrcweir 
209cdf0e10cSrcweir                     ENSURE_OR_THROW( pAlphaReadAccess.get() != NULL,
210cdf0e10cSrcweir                                       "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
211cdf0e10cSrcweir                                       "Unable to acquire read acces to alpha" );
212cdf0e10cSrcweir 
213cdf0e10cSrcweir                     ENSURE_OR_THROW( pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
214cdf0e10cSrcweir                                       pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
215cdf0e10cSrcweir                                       "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
216cdf0e10cSrcweir                                       "Unsupported alpha scanline format" );
217cdf0e10cSrcweir 
218cdf0e10cSrcweir                     BitmapColor		aCol;
219cdf0e10cSrcweir                     const sal_Int32 nWidth( aBmpSize.Width() );
220cdf0e10cSrcweir                     const sal_Int32 nHeight( aBmpSize.Height() );
221cdf0e10cSrcweir                     sal_uInt8* 		pCurrOutput( aBmpData.mpBitmapData.get() );
222cdf0e10cSrcweir                     int 			x, y;
223cdf0e10cSrcweir 
224cdf0e10cSrcweir                     for( y=0; y<nHeight; ++y )
225cdf0e10cSrcweir                     {
226cdf0e10cSrcweir                         switch( pReadAccess->GetScanlineFormat() )
227cdf0e10cSrcweir                         {
228cdf0e10cSrcweir                             case BMP_FORMAT_8BIT_PAL:
229cdf0e10cSrcweir                             {
230cdf0e10cSrcweir                                 Scanline pScan  = pReadAccess->GetScanline( y );
231cdf0e10cSrcweir                                 Scanline pAScan = pAlphaReadAccess->GetScanline( y );
232cdf0e10cSrcweir 
233cdf0e10cSrcweir                                 for( x=0; x<nWidth; ++x )
234cdf0e10cSrcweir                                 {
235cdf0e10cSrcweir                                     aCol = pReadAccess->GetPaletteColor( *pScan++ );
236cdf0e10cSrcweir 
237cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetBlue();
238cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetGreen();
239cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetRed();
240cdf0e10cSrcweir 
241cdf0e10cSrcweir                                     // out notion of alpha is
242cdf0e10cSrcweir                                     // different from the rest
243cdf0e10cSrcweir                                     // of the world's
244cdf0e10cSrcweir                                     *pCurrOutput++ = 255 - (BYTE)*pAScan++;
245cdf0e10cSrcweir                                 }
246cdf0e10cSrcweir                             }
247cdf0e10cSrcweir                             break;
248cdf0e10cSrcweir 
249cdf0e10cSrcweir                             case BMP_FORMAT_24BIT_TC_BGR:
250cdf0e10cSrcweir                             {
251cdf0e10cSrcweir                                 Scanline pScan  = pReadAccess->GetScanline( y );
252cdf0e10cSrcweir                                 Scanline pAScan = pAlphaReadAccess->GetScanline( y );
253cdf0e10cSrcweir 
254cdf0e10cSrcweir                                 for( x=0; x<nWidth; ++x )
255cdf0e10cSrcweir                                 {
256cdf0e10cSrcweir                                     // store as RGBA
257cdf0e10cSrcweir                                     *pCurrOutput++ = *pScan++;
258cdf0e10cSrcweir                                     *pCurrOutput++ = *pScan++;
259cdf0e10cSrcweir                                     *pCurrOutput++ = *pScan++;
260cdf0e10cSrcweir 
261cdf0e10cSrcweir                                     // out notion of alpha is
262cdf0e10cSrcweir                                     // different from the rest
263cdf0e10cSrcweir                                     // of the world's
264cdf0e10cSrcweir                                     *pCurrOutput++ = 255 - (BYTE)*pAScan++;
265cdf0e10cSrcweir                                 }
266cdf0e10cSrcweir                             }
267cdf0e10cSrcweir                             break;
268cdf0e10cSrcweir 
269cdf0e10cSrcweir                             // TODO(P2): Might be advantageous
270cdf0e10cSrcweir                             // to hand-formulate the following
271cdf0e10cSrcweir                             // formats, too.
272cdf0e10cSrcweir                             case BMP_FORMAT_1BIT_MSB_PAL:
273cdf0e10cSrcweir                                 // FALLTHROUGH intended
274cdf0e10cSrcweir                             case BMP_FORMAT_4BIT_MSN_PAL:
275cdf0e10cSrcweir                                 // FALLTHROUGH intended
276cdf0e10cSrcweir                             case BMP_FORMAT_16BIT_TC_LSB_MASK:
277cdf0e10cSrcweir                                 // FALLTHROUGH intended
278cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_MASK:
279cdf0e10cSrcweir                             {
280cdf0e10cSrcweir                                 Scanline pAScan = pAlphaReadAccess->GetScanline( y );
281cdf0e10cSrcweir 
282cdf0e10cSrcweir                                 // using fallback for those
283cdf0e10cSrcweir                                 // seldom formats
284cdf0e10cSrcweir                                 for( x=0; x<nWidth; ++x )
285cdf0e10cSrcweir                                 {
286cdf0e10cSrcweir                                     // yes. x and y are swapped on Get/SetPixel
287cdf0e10cSrcweir                                     aCol = pReadAccess->GetColor(y,x);
288cdf0e10cSrcweir 
289cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetBlue();
290cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetGreen();
291cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetRed();
292cdf0e10cSrcweir 
293cdf0e10cSrcweir                                     // out notion of alpha is
294cdf0e10cSrcweir                                     // different from the rest
295cdf0e10cSrcweir                                     // of the world's
296cdf0e10cSrcweir                                     *pCurrOutput++ = 255 - (BYTE)*pAScan++;
297cdf0e10cSrcweir                                 }
298cdf0e10cSrcweir                             }
299cdf0e10cSrcweir                             break;
300cdf0e10cSrcweir 
301cdf0e10cSrcweir                             case BMP_FORMAT_1BIT_LSB_PAL:
302cdf0e10cSrcweir                                 // FALLTHROUGH intended
303cdf0e10cSrcweir                             case BMP_FORMAT_4BIT_LSN_PAL:
304cdf0e10cSrcweir                                 // FALLTHROUGH intended
305cdf0e10cSrcweir                             case BMP_FORMAT_8BIT_TC_MASK:
306cdf0e10cSrcweir                                 // FALLTHROUGH intended
307cdf0e10cSrcweir                             case BMP_FORMAT_24BIT_TC_RGB:
308cdf0e10cSrcweir                                 // FALLTHROUGH intended
309cdf0e10cSrcweir                             case BMP_FORMAT_24BIT_TC_MASK:
310cdf0e10cSrcweir                                 // FALLTHROUGH intended
311cdf0e10cSrcweir                             case BMP_FORMAT_16BIT_TC_MSB_MASK:
312cdf0e10cSrcweir                                 // FALLTHROUGH intended
313cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_ABGR:
314cdf0e10cSrcweir                                 // FALLTHROUGH intended
315cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_ARGB:
316cdf0e10cSrcweir                                 // FALLTHROUGH intended
317cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_BGRA:
318cdf0e10cSrcweir                                 // FALLTHROUGH intended
319cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_RGBA:
320cdf0e10cSrcweir                                 // FALLTHROUGH intended
321cdf0e10cSrcweir                             default:
322cdf0e10cSrcweir                                 ENSURE_OR_THROW( false,
323cdf0e10cSrcweir                                                   "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
324cdf0e10cSrcweir                                                   "Unexpected scanline format - has "
325cdf0e10cSrcweir                                                   "WinSalBitmap::AcquireBuffer() changed?" );
326cdf0e10cSrcweir                         }
327cdf0e10cSrcweir                     }
328cdf0e10cSrcweir                 }
329cdf0e10cSrcweir                 else
330cdf0e10cSrcweir                 {
331cdf0e10cSrcweir                     Bitmap aMask( rBmpEx.GetMask() );
332cdf0e10cSrcweir 
333cdf0e10cSrcweir                     ScopedBitmapReadAccess pMaskReadAccess( aMask.AcquireReadAccess(),
334cdf0e10cSrcweir                                                             aMask );
335cdf0e10cSrcweir 
336cdf0e10cSrcweir                     // By convention, the access buffer always has
337cdf0e10cSrcweir                     // one of the following formats:
338cdf0e10cSrcweir                     //
339cdf0e10cSrcweir                     //    BMP_FORMAT_1BIT_MSB_PAL
340cdf0e10cSrcweir                     //	  BMP_FORMAT_4BIT_MSN_PAL
341cdf0e10cSrcweir                     //	  BMP_FORMAT_8BIT_PAL
342cdf0e10cSrcweir                     //	  BMP_FORMAT_16BIT_TC_LSB_MASK
343cdf0e10cSrcweir                     //	  BMP_FORMAT_24BIT_TC_BGR
344cdf0e10cSrcweir                     //	  BMP_FORMAT_32BIT_TC_MASK
345cdf0e10cSrcweir                     //
346cdf0e10cSrcweir                     // and is always BMP_FORMAT_BOTTOM_UP
347cdf0e10cSrcweir                     //
348cdf0e10cSrcweir                     // This is the way
349cdf0e10cSrcweir                     // WinSalBitmap::AcquireBuffer() sets up the
350cdf0e10cSrcweir                     // buffer
351cdf0e10cSrcweir 
352cdf0e10cSrcweir                     ENSURE_OR_THROW( pMaskReadAccess.get() != NULL,
353cdf0e10cSrcweir                                       "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
354cdf0e10cSrcweir                                       "Unable to acquire read acces to mask" );
355cdf0e10cSrcweir 
356cdf0e10cSrcweir                     ENSURE_OR_THROW( pMaskReadAccess->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL,
357cdf0e10cSrcweir                                       "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
358cdf0e10cSrcweir                                       "Unsupported mask scanline format" );
359cdf0e10cSrcweir 
360cdf0e10cSrcweir                     BitmapColor		aCol;
361cdf0e10cSrcweir                     int 			nCurrBit;
362cdf0e10cSrcweir                     const int		nMask( 1L );
363cdf0e10cSrcweir                     const int 		nInitialBit(7);
364cdf0e10cSrcweir                     sal_uInt8* 		pCurrOutput( aBmpData.mpBitmapData.get() );
365cdf0e10cSrcweir                     int 			x, y;
366cdf0e10cSrcweir 
367cdf0e10cSrcweir                     // mapping table, to get from mask index color to
368cdf0e10cSrcweir                     // alpha value (which depends on the mask's palette)
369cdf0e10cSrcweir                     sal_uInt8 aColorMap[2];
370cdf0e10cSrcweir 
371cdf0e10cSrcweir                     const BitmapColor& rCol0( pMaskReadAccess->GetPaletteColor( 0 ) );
372cdf0e10cSrcweir                     const BitmapColor& rCol1( pMaskReadAccess->GetPaletteColor( 1 ) );
373cdf0e10cSrcweir 
374cdf0e10cSrcweir                     // shortcut for true luminance calculation
375cdf0e10cSrcweir                     // (assumes that palette is grey-level). Note the
376cdf0e10cSrcweir                     // swapped the indices here, to account for the
377cdf0e10cSrcweir                     // fact that VCL's notion of alpha is inverted to
378cdf0e10cSrcweir                     // the rest of the world's.
379cdf0e10cSrcweir                     aColorMap[0] = rCol1.GetRed();
380cdf0e10cSrcweir                     aColorMap[1] = rCol0.GetRed();
381cdf0e10cSrcweir 
382cdf0e10cSrcweir                     for( y=0; y<nHeight; ++y )
383cdf0e10cSrcweir                     {
384cdf0e10cSrcweir                         switch( pReadAccess->GetScanlineFormat() )
385cdf0e10cSrcweir                         {
386cdf0e10cSrcweir                             case BMP_FORMAT_8BIT_PAL:
387cdf0e10cSrcweir                             {
388cdf0e10cSrcweir                                 Scanline pScan  = pReadAccess->GetScanline( y );
389cdf0e10cSrcweir                                 Scanline pMScan = pMaskReadAccess->GetScanline( y );
390cdf0e10cSrcweir 
391cdf0e10cSrcweir                                 for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
392cdf0e10cSrcweir                                 {
393cdf0e10cSrcweir                                     aCol = pReadAccess->GetPaletteColor( *pScan++ );
394cdf0e10cSrcweir 
395cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetBlue();
396cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetGreen();
397cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetRed();
398cdf0e10cSrcweir 
399cdf0e10cSrcweir                                     *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ];
400cdf0e10cSrcweir                                     nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
401cdf0e10cSrcweir                                 }
402cdf0e10cSrcweir                             }
403cdf0e10cSrcweir                             break;
404cdf0e10cSrcweir 
405cdf0e10cSrcweir                             case BMP_FORMAT_24BIT_TC_BGR:
406cdf0e10cSrcweir                             {
407cdf0e10cSrcweir                                 Scanline pScan  = pReadAccess->GetScanline( y );
408cdf0e10cSrcweir                                 Scanline pMScan = pMaskReadAccess->GetScanline( y );
409cdf0e10cSrcweir 
410cdf0e10cSrcweir                                 for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
411cdf0e10cSrcweir                                 {
412cdf0e10cSrcweir                                     // store as RGBA
413cdf0e10cSrcweir                                     *pCurrOutput++ = *pScan++;
414cdf0e10cSrcweir                                     *pCurrOutput++ = *pScan++;
415cdf0e10cSrcweir                                     *pCurrOutput++ = *pScan++;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir                                     *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ];
418cdf0e10cSrcweir                                     nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
419cdf0e10cSrcweir                                 }
420cdf0e10cSrcweir                             }
421cdf0e10cSrcweir                             break;
422cdf0e10cSrcweir 
423cdf0e10cSrcweir                             // TODO(P2): Might be advantageous
424cdf0e10cSrcweir                             // to hand-formulate the following
425cdf0e10cSrcweir                             // formats, too.
426cdf0e10cSrcweir                             case BMP_FORMAT_1BIT_MSB_PAL:
427cdf0e10cSrcweir                                 // FALLTHROUGH intended
428cdf0e10cSrcweir                             case BMP_FORMAT_4BIT_MSN_PAL:
429cdf0e10cSrcweir                                 // FALLTHROUGH intended
430cdf0e10cSrcweir                             case BMP_FORMAT_16BIT_TC_LSB_MASK:
431cdf0e10cSrcweir                                 // FALLTHROUGH intended
432cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_MASK:
433cdf0e10cSrcweir                             {
434cdf0e10cSrcweir                                 Scanline pMScan = pMaskReadAccess->GetScanline( y );
435cdf0e10cSrcweir 
436cdf0e10cSrcweir                                 // using fallback for those
437cdf0e10cSrcweir                                 // seldom formats
438cdf0e10cSrcweir                                 for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
439cdf0e10cSrcweir                                 {
440cdf0e10cSrcweir                                     // yes. x and y are swapped on Get/SetPixel
441cdf0e10cSrcweir                                     aCol = pReadAccess->GetColor(y,x);
442cdf0e10cSrcweir 
443cdf0e10cSrcweir                                     // store as RGBA
444cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetBlue();
445cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetGreen();
446cdf0e10cSrcweir                                     *pCurrOutput++ = aCol.GetRed();
447cdf0e10cSrcweir 
448cdf0e10cSrcweir                                     *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ];
449cdf0e10cSrcweir                                     nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
450cdf0e10cSrcweir                                 }
451cdf0e10cSrcweir                             }
452cdf0e10cSrcweir                             break;
453cdf0e10cSrcweir 
454cdf0e10cSrcweir                             case BMP_FORMAT_1BIT_LSB_PAL:
455cdf0e10cSrcweir                                 // FALLTHROUGH intended
456cdf0e10cSrcweir                             case BMP_FORMAT_4BIT_LSN_PAL:
457cdf0e10cSrcweir                                 // FALLTHROUGH intended
458cdf0e10cSrcweir                             case BMP_FORMAT_8BIT_TC_MASK:
459cdf0e10cSrcweir                                 // FALLTHROUGH intended
460cdf0e10cSrcweir                             case BMP_FORMAT_24BIT_TC_RGB:
461cdf0e10cSrcweir                                 // FALLTHROUGH intended
462cdf0e10cSrcweir                             case BMP_FORMAT_24BIT_TC_MASK:
463cdf0e10cSrcweir                                 // FALLTHROUGH intended
464cdf0e10cSrcweir                             case BMP_FORMAT_16BIT_TC_MSB_MASK:
465cdf0e10cSrcweir                                 // FALLTHROUGH intended
466cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_ABGR:
467cdf0e10cSrcweir                                 // FALLTHROUGH intended
468cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_ARGB:
469cdf0e10cSrcweir                                 // FALLTHROUGH intended
470cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_BGRA:
471cdf0e10cSrcweir                                 // FALLTHROUGH intended
472cdf0e10cSrcweir                             case BMP_FORMAT_32BIT_TC_RGBA:
473cdf0e10cSrcweir                                 // FALLTHROUGH intended
474cdf0e10cSrcweir                             default:
475cdf0e10cSrcweir                                 ENSURE_OR_THROW( false,
476cdf0e10cSrcweir                                                   "::dxcanvas::tools::bitmapFromVCLBitmapEx(): "
477cdf0e10cSrcweir                                                   "Unexpected scanline format - has "
478cdf0e10cSrcweir                                                   "WinSalBitmap::AcquireBuffer() changed?" );
479cdf0e10cSrcweir                         }
480cdf0e10cSrcweir                     }
481cdf0e10cSrcweir                 }
482cdf0e10cSrcweir 
483cdf0e10cSrcweir                 return aBmpData;
484cdf0e10cSrcweir             }
485cdf0e10cSrcweir 
drawVCLBitmapEx(const::boost::shared_ptr<Gdiplus::Graphics> & rGraphics,const::BitmapEx & rBmpEx)486cdf0e10cSrcweir             bool drawVCLBitmapEx( const ::boost::shared_ptr< Gdiplus::Graphics >& rGraphics,
487cdf0e10cSrcweir                                   const ::BitmapEx& 							  rBmpEx )
488cdf0e10cSrcweir             {
489cdf0e10cSrcweir                 if( !rBmpEx.IsTransparent() )
490cdf0e10cSrcweir                 {
491cdf0e10cSrcweir                     Bitmap aBmp( rBmpEx.GetBitmap() );
492cdf0e10cSrcweir                     return drawVCLBitmap( rGraphics, aBmp );
493cdf0e10cSrcweir                 }
494cdf0e10cSrcweir                 else
495cdf0e10cSrcweir                 {
496cdf0e10cSrcweir                     return drawRGBABits( rGraphics,
497cdf0e10cSrcweir                                          bitmapFromVCLBitmapEx( rBmpEx ) );
498cdf0e10cSrcweir                 }
499cdf0e10cSrcweir             }
500cdf0e10cSrcweir         }
501cdf0e10cSrcweir 
drawVCLBitmapFromXBitmap(const::boost::shared_ptr<Gdiplus::Graphics> & rGraphics,const uno::Reference<rendering::XBitmap> & xBitmap)502cdf0e10cSrcweir         bool drawVCLBitmapFromXBitmap( const ::boost::shared_ptr< Gdiplus::Graphics >& rGraphics,
503cdf0e10cSrcweir                                        const uno::Reference< rendering::XBitmap >&	   xBitmap )
504cdf0e10cSrcweir         {
505cdf0e10cSrcweir             // TODO(F2): add support for floating point bitmap formats
506cdf0e10cSrcweir             uno::Reference< rendering::XIntegerReadOnlyBitmap > xIntBmp(
507cdf0e10cSrcweir                 xBitmap, uno::UNO_QUERY );
508cdf0e10cSrcweir 
509cdf0e10cSrcweir             if( !xIntBmp.is() )
510cdf0e10cSrcweir                 return false;
511cdf0e10cSrcweir 
512cdf0e10cSrcweir             ::BitmapEx aBmpEx = ::vcl::unotools::bitmapExFromXBitmap( xIntBmp );
513cdf0e10cSrcweir             if( !aBmpEx )
514cdf0e10cSrcweir                 return false;
515cdf0e10cSrcweir 
516cdf0e10cSrcweir             return drawVCLBitmapEx( rGraphics, aBmpEx );
517cdf0e10cSrcweir         }
518cdf0e10cSrcweir     }
519cdf0e10cSrcweir }
520