xref: /trunk/main/canvas/source/directx/dx_surfacebitmap.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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
10cdf0e10cSrcweir  *
1125ea7f45SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
2025ea7f45SAndrew Rist  *************************************************************/
2125ea7f45SAndrew Rist 
2225ea7f45SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_canvas.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "dx_surfacebitmap.hxx"
28cdf0e10cSrcweir #include "dx_impltools.hxx"
29cdf0e10cSrcweir #include "dx_surfacegraphics.hxx"
30cdf0e10cSrcweir #include "dx_graphicsprovider.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <canvas/debug.hxx>
33cdf0e10cSrcweir #include <tools/diagnose_ex.h>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
36cdf0e10cSrcweir #include <basegfx/range/b2irange.hxx>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #if defined(DX_DEBUG_IMAGES)
39cdf0e10cSrcweir # if OSL_DEBUG_LEVEL > 0
40cdf0e10cSrcweir #  include <imdebug.h>
41cdf0e10cSrcweir #  undef min
42cdf0e10cSrcweir #  undef max
43cdf0e10cSrcweir # endif
44cdf0e10cSrcweir #endif
45cdf0e10cSrcweir 
46cdf0e10cSrcweir using namespace ::com::sun::star;
47cdf0e10cSrcweir 
48cdf0e10cSrcweir namespace dxcanvas
49cdf0e10cSrcweir {
50cdf0e10cSrcweir     namespace
51cdf0e10cSrcweir     {
52cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////////////////////
53cdf0e10cSrcweir         // DXColorBuffer
54cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////////////////////
55cdf0e10cSrcweir 
56cdf0e10cSrcweir         struct DXColorBuffer : public canvas::IColorBuffer
57cdf0e10cSrcweir         {
58cdf0e10cSrcweir         public:
DXColorBufferdxcanvas::__anon5b5ab5850111::DXColorBuffer59cdf0e10cSrcweir             DXColorBuffer( const COMReference<surface_type>& rSurface,
60cdf0e10cSrcweir                            const ::basegfx::B2IVector&       rSize ) :
61cdf0e10cSrcweir                 mpSurface(rSurface),
62cdf0e10cSrcweir                 maSize(rSize),
63cdf0e10cSrcweir                 mbAlpha(false)
64cdf0e10cSrcweir             {
65cdf0e10cSrcweir             }
66cdf0e10cSrcweir 
67cdf0e10cSrcweir         // implementation of the 'IColorBuffer' interface
68cdf0e10cSrcweir         public:
69cdf0e10cSrcweir 
70cdf0e10cSrcweir             virtual sal_uInt8* lock() const;
71cdf0e10cSrcweir             virtual void       unlock() const;
72cdf0e10cSrcweir             virtual sal_uInt32 getWidth() const;
73cdf0e10cSrcweir             virtual sal_uInt32 getHeight() const;
74cdf0e10cSrcweir             virtual sal_uInt32 getStride() const;
75cdf0e10cSrcweir             virtual Format     getFormat() const;
76cdf0e10cSrcweir 
77cdf0e10cSrcweir         private:
78cdf0e10cSrcweir 
79cdf0e10cSrcweir             ::basegfx::B2IVector maSize;
80cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
81cdf0e10cSrcweir             mutable DDSURFACEDESC aSurfaceDesc;
82cdf0e10cSrcweir #else
83cdf0e10cSrcweir             mutable D3DLOCKED_RECT maLockedRect;
84cdf0e10cSrcweir #endif
85cdf0e10cSrcweir             mutable COMReference<surface_type> mpSurface;
86cdf0e10cSrcweir             bool mbAlpha;
87cdf0e10cSrcweir         };
88cdf0e10cSrcweir 
lock() const89cdf0e10cSrcweir         sal_uInt8* DXColorBuffer::lock() const
90cdf0e10cSrcweir         {
91cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
92cdf0e10cSrcweir             rtl_fillMemory((void *)&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
93cdf0e10cSrcweir             aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
94cdf0e10cSrcweir             const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
95cdf0e10cSrcweir             if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
96cdf0e10cSrcweir                 return static_cast<sal_uInt8 *>(aSurfaceDesc.lpSurface);
97cdf0e10cSrcweir #else
98cdf0e10cSrcweir             if(SUCCEEDED(mpSurface->LockRect(&maLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
99cdf0e10cSrcweir                 return static_cast<sal_uInt8 *>(maLockedRect.pBits);
100cdf0e10cSrcweir #endif
101cdf0e10cSrcweir             return NULL;
102cdf0e10cSrcweir         }
103cdf0e10cSrcweir 
unlock() const104cdf0e10cSrcweir         void DXColorBuffer::unlock() const
105cdf0e10cSrcweir         {
106cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
107cdf0e10cSrcweir             mpSurface->Unlock(NULL);
108cdf0e10cSrcweir #else
109cdf0e10cSrcweir             mpSurface->UnlockRect();
110cdf0e10cSrcweir #endif
111cdf0e10cSrcweir         }
112cdf0e10cSrcweir 
getWidth() const113cdf0e10cSrcweir         sal_uInt32 DXColorBuffer::getWidth() const
114cdf0e10cSrcweir         {
115cdf0e10cSrcweir             return maSize.getX();
116cdf0e10cSrcweir         }
117cdf0e10cSrcweir 
getHeight() const118cdf0e10cSrcweir         sal_uInt32 DXColorBuffer::getHeight() const
119cdf0e10cSrcweir         {
120cdf0e10cSrcweir             return maSize.getY();
121cdf0e10cSrcweir         }
122cdf0e10cSrcweir 
getStride() const123cdf0e10cSrcweir         sal_uInt32 DXColorBuffer::getStride() const
124cdf0e10cSrcweir         {
125cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
126cdf0e10cSrcweir             return aSurfaceDesc.lPitch;
127cdf0e10cSrcweir #else
128cdf0e10cSrcweir             return maLockedRect.Pitch;
129cdf0e10cSrcweir #endif
130cdf0e10cSrcweir         }
131cdf0e10cSrcweir 
getFormat() const132cdf0e10cSrcweir         canvas::IColorBuffer::Format DXColorBuffer::getFormat() const
133cdf0e10cSrcweir         {
134cdf0e10cSrcweir             return canvas::IColorBuffer::FMT_X8R8G8B8;
135cdf0e10cSrcweir         }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////////////////////
138cdf0e10cSrcweir         // GDIColorBuffer
139cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////////////////////
140cdf0e10cSrcweir 
141cdf0e10cSrcweir         struct GDIColorBuffer : public canvas::IColorBuffer
142cdf0e10cSrcweir         {
143cdf0e10cSrcweir         public:
144cdf0e10cSrcweir 
GDIColorBufferdxcanvas::__anon5b5ab5850111::GDIColorBuffer145cdf0e10cSrcweir             GDIColorBuffer( const BitmapSharedPtr&      rSurface,
146cdf0e10cSrcweir                             const ::basegfx::B2IVector& rSize ) :
147cdf0e10cSrcweir                 mpGDIPlusBitmap(rSurface),
148cdf0e10cSrcweir                 maSize(rSize),
149cdf0e10cSrcweir                 mbAlpha(true)
150cdf0e10cSrcweir             {
151cdf0e10cSrcweir             }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir         // implementation of the 'IColorBuffer' interface
154cdf0e10cSrcweir         public:
155cdf0e10cSrcweir 
156cdf0e10cSrcweir             virtual sal_uInt8* lock() const;
157cdf0e10cSrcweir             virtual void       unlock() const;
158cdf0e10cSrcweir             virtual sal_uInt32 getWidth() const;
159cdf0e10cSrcweir             virtual sal_uInt32 getHeight() const;
160cdf0e10cSrcweir             virtual sal_uInt32 getStride() const;
161cdf0e10cSrcweir             virtual Format     getFormat() const;
162cdf0e10cSrcweir 
163cdf0e10cSrcweir         private:
164cdf0e10cSrcweir 
165cdf0e10cSrcweir             ::basegfx::B2IVector maSize;
166cdf0e10cSrcweir             mutable Gdiplus::BitmapData aBmpData;
167cdf0e10cSrcweir             BitmapSharedPtr mpGDIPlusBitmap;
168cdf0e10cSrcweir             bool mbAlpha;
169cdf0e10cSrcweir         };
170cdf0e10cSrcweir 
lock() const171cdf0e10cSrcweir         sal_uInt8* GDIColorBuffer::lock() const
172cdf0e10cSrcweir         {
173cdf0e10cSrcweir             aBmpData.Width = maSize.getX();
174cdf0e10cSrcweir             aBmpData.Height = maSize.getY();
175cdf0e10cSrcweir             aBmpData.Stride = 4*aBmpData.Width;
176cdf0e10cSrcweir             aBmpData.PixelFormat = PixelFormat32bppARGB;
177cdf0e10cSrcweir             aBmpData.Scan0 = NULL;
178cdf0e10cSrcweir             const Gdiplus::Rect aRect( 0,0,aBmpData.Width,aBmpData.Height );
179cdf0e10cSrcweir             if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
180cdf0e10cSrcweir                                                           Gdiplus::ImageLockModeRead,
181cdf0e10cSrcweir                                                           PixelFormat32bppARGB,
182cdf0e10cSrcweir                                                           &aBmpData ) )
183cdf0e10cSrcweir             {
184cdf0e10cSrcweir                 return NULL;
185cdf0e10cSrcweir             }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir             return static_cast<sal_uInt8*>(aBmpData.Scan0);
188cdf0e10cSrcweir         }
189cdf0e10cSrcweir 
unlock() const190cdf0e10cSrcweir         void GDIColorBuffer::unlock() const
191cdf0e10cSrcweir         {
192cdf0e10cSrcweir             mpGDIPlusBitmap->UnlockBits( &aBmpData );
193cdf0e10cSrcweir         }
194cdf0e10cSrcweir 
getWidth() const195cdf0e10cSrcweir         sal_uInt32 GDIColorBuffer::getWidth() const
196cdf0e10cSrcweir         {
197cdf0e10cSrcweir             return maSize.getX();
198cdf0e10cSrcweir         }
199cdf0e10cSrcweir 
getHeight() const200cdf0e10cSrcweir         sal_uInt32 GDIColorBuffer::getHeight() const
201cdf0e10cSrcweir         {
202cdf0e10cSrcweir             return maSize.getY();
203cdf0e10cSrcweir         }
204cdf0e10cSrcweir 
getStride() const205cdf0e10cSrcweir         sal_uInt32 GDIColorBuffer::getStride() const
206cdf0e10cSrcweir         {
207cdf0e10cSrcweir             return aBmpData.Stride;
208cdf0e10cSrcweir         }
209cdf0e10cSrcweir 
getFormat() const210cdf0e10cSrcweir         canvas::IColorBuffer::Format GDIColorBuffer::getFormat() const
211cdf0e10cSrcweir         {
212cdf0e10cSrcweir             return canvas::IColorBuffer::FMT_A8R8G8B8;
213cdf0e10cSrcweir         }
214cdf0e10cSrcweir     }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
217cdf0e10cSrcweir     // DXSurfaceBitmap::DXSurfaceBitmap
218cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
219cdf0e10cSrcweir 
DXSurfaceBitmap(const::basegfx::B2IVector & rSize,const canvas::ISurfaceProxyManagerSharedPtr & rMgr,const IDXRenderModuleSharedPtr & rRenderModule,bool bWithAlpha)220cdf0e10cSrcweir     DXSurfaceBitmap::DXSurfaceBitmap( const ::basegfx::B2IVector&                   rSize,
221cdf0e10cSrcweir                                       const canvas::ISurfaceProxyManagerSharedPtr&  rMgr,
222cdf0e10cSrcweir                                       const IDXRenderModuleSharedPtr&               rRenderModule,
223cdf0e10cSrcweir                                       bool                                          bWithAlpha ) :
224cdf0e10cSrcweir         mpGdiPlusUser( GDIPlusUser::createInstance() ),
225cdf0e10cSrcweir         maSize(rSize),
226cdf0e10cSrcweir         mpRenderModule(rRenderModule),
227cdf0e10cSrcweir         mpSurfaceManager(rMgr),
228cdf0e10cSrcweir         mpSurfaceProxy(),
229cdf0e10cSrcweir         mpSurface(),
230cdf0e10cSrcweir         mpGDIPlusBitmap(),
231cdf0e10cSrcweir         mpGraphics(),
232cdf0e10cSrcweir         mpColorBuffer(),
233cdf0e10cSrcweir         mbIsSurfaceDirty(true),
234cdf0e10cSrcweir         mbAlpha(bWithAlpha)
235cdf0e10cSrcweir     {
236cdf0e10cSrcweir         init();
237cdf0e10cSrcweir     }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
240cdf0e10cSrcweir     // DXSurfaceBitmap::getSize
241cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
242cdf0e10cSrcweir 
getSize() const243cdf0e10cSrcweir     ::basegfx::B2IVector DXSurfaceBitmap::getSize() const
244cdf0e10cSrcweir     {
245cdf0e10cSrcweir         return maSize;
246cdf0e10cSrcweir     }
247cdf0e10cSrcweir 
248cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
249cdf0e10cSrcweir     // DXSurfaceBitmap::init
250cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
251cdf0e10cSrcweir 
init()252cdf0e10cSrcweir     void DXSurfaceBitmap::init()
253cdf0e10cSrcweir     {
254cdf0e10cSrcweir         // create container for pixel data
255cdf0e10cSrcweir         if(mbAlpha)
256cdf0e10cSrcweir         {
257cdf0e10cSrcweir             mpGDIPlusBitmap.reset(
258cdf0e10cSrcweir                 new Gdiplus::Bitmap(
259cdf0e10cSrcweir                     maSize.getX(),
260cdf0e10cSrcweir                     maSize.getY(),
261cdf0e10cSrcweir                     PixelFormat32bppARGB
262cdf0e10cSrcweir                     ));
263cdf0e10cSrcweir             mpGraphics.reset( tools::createGraphicsFromBitmap(mpGDIPlusBitmap) );
264cdf0e10cSrcweir 
265cdf0e10cSrcweir             // create the colorbuffer object, which is basically a simple
266cdf0e10cSrcweir             // wrapper around the directx surface. the colorbuffer is the
267cdf0e10cSrcweir             // interface which is used by the surfaceproxy to support any
268cdf0e10cSrcweir             // kind of underlying structure for the pixel data container.
269cdf0e10cSrcweir             mpColorBuffer.reset(new GDIColorBuffer(mpGDIPlusBitmap,maSize));
270cdf0e10cSrcweir         }
271cdf0e10cSrcweir         else
272cdf0e10cSrcweir         {
273cdf0e10cSrcweir             mpSurface = mpRenderModule->createSystemMemorySurface(maSize);
274cdf0e10cSrcweir 
275cdf0e10cSrcweir             // create the colorbuffer object, which is basically a simple
276cdf0e10cSrcweir             // wrapper around the directx surface. the colorbuffer is the
277cdf0e10cSrcweir             // interface which is used by the surfaceproxy to support any
278cdf0e10cSrcweir             // kind of underlying structure for the pixel data container.
279cdf0e10cSrcweir             mpColorBuffer.reset(new DXColorBuffer(mpSurface,maSize));
280cdf0e10cSrcweir         }
281cdf0e10cSrcweir 
282cdf0e10cSrcweir         // create a (possibly hardware accelerated) mirror surface.
283cdf0e10cSrcweir         mpSurfaceProxy = mpSurfaceManager->createSurfaceProxy(mpColorBuffer);
284cdf0e10cSrcweir     }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
287cdf0e10cSrcweir     // DXSurfaceBitmap::resize
288cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
289cdf0e10cSrcweir 
resize(const::basegfx::B2IVector & rSize)290cdf0e10cSrcweir     bool DXSurfaceBitmap::resize( const ::basegfx::B2IVector& rSize )
291cdf0e10cSrcweir     {
292cdf0e10cSrcweir         if(maSize != rSize)
293cdf0e10cSrcweir         {
294cdf0e10cSrcweir             maSize = rSize;
295cdf0e10cSrcweir             init();
296cdf0e10cSrcweir         }
297cdf0e10cSrcweir 
298cdf0e10cSrcweir         return true;
299cdf0e10cSrcweir     }
300cdf0e10cSrcweir 
301cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
302cdf0e10cSrcweir     // DXSurfaceBitmap::clear
303cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
304cdf0e10cSrcweir 
clear()305cdf0e10cSrcweir     void DXSurfaceBitmap::clear()
306cdf0e10cSrcweir     {
307cdf0e10cSrcweir         GraphicsSharedPtr pGraphics(getGraphics());
308cdf0e10cSrcweir         Gdiplus::Color transColor(255,0,0,0);
309cdf0e10cSrcweir         pGraphics->SetCompositingMode( Gdiplus::CompositingModeSourceCopy );
310cdf0e10cSrcweir         pGraphics->Clear( transColor );
311cdf0e10cSrcweir     }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
314cdf0e10cSrcweir     // DXSurfaceBitmap::hasAlpha
315cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
316cdf0e10cSrcweir 
hasAlpha() const317cdf0e10cSrcweir     bool DXSurfaceBitmap::hasAlpha() const
318cdf0e10cSrcweir     {
319cdf0e10cSrcweir         return mbAlpha;
320cdf0e10cSrcweir     }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
323cdf0e10cSrcweir     // DXSurfaceBitmap::getGraphics
324cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
325cdf0e10cSrcweir 
getGraphics()326cdf0e10cSrcweir     GraphicsSharedPtr DXSurfaceBitmap::getGraphics()
327cdf0e10cSrcweir     {
328cdf0e10cSrcweir         // since clients will most probably draw directly
329cdf0e10cSrcweir         // to the GDI+ bitmap, we need to mark it as dirty
330*dcaf07f7SJohn Bampton         // to ensure that the corresponding dxsurface will
331cdf0e10cSrcweir         // be updated.
332cdf0e10cSrcweir         mbIsSurfaceDirty = true;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir         if(hasAlpha())
335cdf0e10cSrcweir             return mpGraphics;
336cdf0e10cSrcweir         else
337cdf0e10cSrcweir             return createSurfaceGraphics(mpSurface);
338cdf0e10cSrcweir     }
339cdf0e10cSrcweir 
340cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
341cdf0e10cSrcweir     // DXSurfaceBitmap::getBitmap
342cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
343cdf0e10cSrcweir 
getBitmap() const344cdf0e10cSrcweir     BitmapSharedPtr DXSurfaceBitmap::getBitmap() const
345cdf0e10cSrcweir     {
346cdf0e10cSrcweir         if(hasAlpha())
347cdf0e10cSrcweir             return mpGDIPlusBitmap;
348cdf0e10cSrcweir 
349cdf0e10cSrcweir         BitmapSharedPtr pResult;
350cdf0e10cSrcweir 
351cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
352cdf0e10cSrcweir         DDSURFACEDESC aSurfaceDesc;
353cdf0e10cSrcweir         rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
354cdf0e10cSrcweir         aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
355cdf0e10cSrcweir         const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
356cdf0e10cSrcweir 
357cdf0e10cSrcweir         // lock the directx surface to receive the pointer to the surface memory.
358cdf0e10cSrcweir         if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
359cdf0e10cSrcweir         {
360cdf0e10cSrcweir             // decide about the format we pass the gdi+, the directx surface is always
361cdf0e10cSrcweir             // 32bit, either with or without alpha component.
362cdf0e10cSrcweir             Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB;
363cdf0e10cSrcweir 
364cdf0e10cSrcweir             // construct a gdi+ bitmap from the raw pixel data.
365cdf0e10cSrcweir             pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(),
366cdf0e10cSrcweir                                                aSurfaceDesc.lPitch,
367cdf0e10cSrcweir                                                nFormat,
368cdf0e10cSrcweir                                                (BYTE *)aSurfaceDesc.lpSurface ));
369cdf0e10cSrcweir 
370cdf0e10cSrcweir             // unlock the directx surface
371cdf0e10cSrcweir             mpSurface->Unlock(NULL);
372cdf0e10cSrcweir         }
373cdf0e10cSrcweir #else
374cdf0e10cSrcweir         D3DLOCKED_RECT aLockedRect;
375cdf0e10cSrcweir         if(SUCCEEDED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
376cdf0e10cSrcweir         {
377cdf0e10cSrcweir             // decide about the format we pass the gdi+, the directx surface is always
378cdf0e10cSrcweir             // 32bit, either with or without alpha component.
379cdf0e10cSrcweir             Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB;
380cdf0e10cSrcweir 
381cdf0e10cSrcweir             // construct a gdi+ bitmap from the raw pixel data.
382cdf0e10cSrcweir             pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(),
383cdf0e10cSrcweir                                                 aLockedRect.Pitch,
384cdf0e10cSrcweir                                                 nFormat,
385cdf0e10cSrcweir                                                 (BYTE *)aLockedRect.pBits ));
386cdf0e10cSrcweir 
387cdf0e10cSrcweir             mpSurface->UnlockRect();
388cdf0e10cSrcweir         }
389cdf0e10cSrcweir #endif
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         return pResult;
392cdf0e10cSrcweir     }
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
395cdf0e10cSrcweir     // DXSurfaceBitmap::draw
396cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
397cdf0e10cSrcweir 
draw(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DPolyPolygon & rClipPoly,const::basegfx::B2DHomMatrix & rTransform)398cdf0e10cSrcweir     bool DXSurfaceBitmap::draw( double                           fAlpha,
399cdf0e10cSrcweir                                 const ::basegfx::B2DPoint&       rPos,
400cdf0e10cSrcweir                                 const ::basegfx::B2DPolyPolygon& rClipPoly,
401cdf0e10cSrcweir                                 const ::basegfx::B2DHomMatrix&   rTransform )
402cdf0e10cSrcweir     {
403cdf0e10cSrcweir         if( mbIsSurfaceDirty )
404cdf0e10cSrcweir         {
405cdf0e10cSrcweir             mpSurfaceProxy->setColorBufferDirty();
406cdf0e10cSrcweir             mbIsSurfaceDirty = false;
407cdf0e10cSrcweir         }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir         return mpSurfaceProxy->draw( fAlpha, rPos, rClipPoly, rTransform );
410cdf0e10cSrcweir     }
411cdf0e10cSrcweir 
412cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
413cdf0e10cSrcweir     // DXSurfaceBitmap::draw
414cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
415cdf0e10cSrcweir 
draw(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DRange & rArea,const::basegfx::B2DHomMatrix & rTransform)416cdf0e10cSrcweir     bool DXSurfaceBitmap::draw( double                         fAlpha,
417cdf0e10cSrcweir                                 const ::basegfx::B2DPoint&     rPos,
418cdf0e10cSrcweir                                 const ::basegfx::B2DRange&     rArea,
419cdf0e10cSrcweir                                 const ::basegfx::B2DHomMatrix& rTransform )
420cdf0e10cSrcweir     {
421cdf0e10cSrcweir         if( mbIsSurfaceDirty )
422cdf0e10cSrcweir         {
423cdf0e10cSrcweir             mpSurfaceProxy->setColorBufferDirty();
424cdf0e10cSrcweir             mbIsSurfaceDirty = false;
425cdf0e10cSrcweir         }
426cdf0e10cSrcweir 
427cdf0e10cSrcweir         return mpSurfaceProxy->draw( fAlpha, rPos, rArea, rTransform );
428cdf0e10cSrcweir     }
429cdf0e10cSrcweir 
430cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
431cdf0e10cSrcweir     // DXSurfaceBitmap::draw
432cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
433cdf0e10cSrcweir 
draw(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DHomMatrix & rTransform)434cdf0e10cSrcweir     bool DXSurfaceBitmap::draw( double                         fAlpha,
435cdf0e10cSrcweir                                 const ::basegfx::B2DPoint&     rPos,
436cdf0e10cSrcweir                                 const ::basegfx::B2DHomMatrix& rTransform )
437cdf0e10cSrcweir     {
438cdf0e10cSrcweir         if( mbIsSurfaceDirty )
439cdf0e10cSrcweir         {
440cdf0e10cSrcweir             mpSurfaceProxy->setColorBufferDirty();
441cdf0e10cSrcweir             mbIsSurfaceDirty = false;
442cdf0e10cSrcweir         }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir         return mpSurfaceProxy->draw( fAlpha, rPos, rTransform );
445cdf0e10cSrcweir     }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
448cdf0e10cSrcweir     // DXSurfaceBitmap::draw
449cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
450cdf0e10cSrcweir 
draw(const::basegfx::B2IRange & rArea)451cdf0e10cSrcweir     bool DXSurfaceBitmap::draw( const ::basegfx::B2IRange& rArea )
452cdf0e10cSrcweir     {
453cdf0e10cSrcweir         if( mbIsSurfaceDirty )
454cdf0e10cSrcweir         {
455cdf0e10cSrcweir             mpSurfaceProxy->setColorBufferDirty();
456cdf0e10cSrcweir             mbIsSurfaceDirty = false;
457cdf0e10cSrcweir         }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir         const double                  fAlpha(1.0);
460cdf0e10cSrcweir         const ::basegfx::B2DHomMatrix aTransform;
461cdf0e10cSrcweir         const ::basegfx::B2DRange     aIEEEArea( rArea );
462cdf0e10cSrcweir         return mpSurfaceProxy->draw(fAlpha,
463cdf0e10cSrcweir                                     ::basegfx::B2DPoint(),
464cdf0e10cSrcweir                                     aIEEEArea,
465cdf0e10cSrcweir                                     aTransform);
466cdf0e10cSrcweir     }
467cdf0e10cSrcweir 
468cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
469cdf0e10cSrcweir     // DXSurfaceBitmap::imageDebugger
470cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
471cdf0e10cSrcweir #if defined(DX_DEBUG_IMAGES)
472cdf0e10cSrcweir # if OSL_DEBUG_LEVEL > 0
imageDebugger()473cdf0e10cSrcweir     void DXSurfaceBitmap::imageDebugger()
474cdf0e10cSrcweir     {
475cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
476cdf0e10cSrcweir         DDSURFACEDESC aSurfaceDesc;
477cdf0e10cSrcweir         rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 );
478cdf0e10cSrcweir         aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
479cdf0e10cSrcweir 
480cdf0e10cSrcweir         if( FAILED(mpSurface->Lock( NULL,
481cdf0e10cSrcweir                                     &aSurfaceDesc,
482cdf0e10cSrcweir                                     DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY,
483cdf0e10cSrcweir                                     NULL)) )
484cdf0e10cSrcweir             return;
485cdf0e10cSrcweir 
486cdf0e10cSrcweir         imdebug("bgra w=%d h=%d %p", aSurfaceDesc.dwWidth, aSurfaceDesc.dwHeight, aSurfaceDesc.lpSurface);
487cdf0e10cSrcweir 
488cdf0e10cSrcweir         mpSurface->Unlock(NULL);
489cdf0e10cSrcweir #else
490cdf0e10cSrcweir         D3DLOCKED_RECT aLockedRect;
491cdf0e10cSrcweir         if( FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)) )
492cdf0e10cSrcweir             return;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir         imdebug("bgra w=%d h=%d %p", maSize.getX(),
495cdf0e10cSrcweir                 maSize.getY(), aLockedRect.pBits);
496cdf0e10cSrcweir         mpSurface->UnlockRect();
497cdf0e10cSrcweir #endif
498cdf0e10cSrcweir     }
499cdf0e10cSrcweir # endif
500cdf0e10cSrcweir #endif
501cdf0e10cSrcweir 
502cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
503cdf0e10cSrcweir     // DXSurfaceBitmap::getData
504cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
505cdf0e10cSrcweir 
getData(rendering::IntegerBitmapLayout &,const geometry::IntegerRectangle2D & rect)506cdf0e10cSrcweir     uno::Sequence< sal_Int8 > DXSurfaceBitmap::getData( rendering::IntegerBitmapLayout&     /*bitmapLayout*/,
507cdf0e10cSrcweir                                                         const geometry::IntegerRectangle2D& rect )
508cdf0e10cSrcweir     {
509cdf0e10cSrcweir         if(hasAlpha())
510cdf0e10cSrcweir         {
511cdf0e10cSrcweir             uno::Sequence< sal_Int8 > aRes( (rect.X2-rect.X1)*(rect.Y2-rect.Y1)*4 ); // TODO(F1): Be format-agnostic here
512cdf0e10cSrcweir 
513cdf0e10cSrcweir             const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
514cdf0e10cSrcweir 
515cdf0e10cSrcweir             Gdiplus::BitmapData aBmpData;
516cdf0e10cSrcweir             aBmpData.Width       = rect.X2-rect.X1;
517cdf0e10cSrcweir             aBmpData.Height      = rect.Y2-rect.Y1;
518cdf0e10cSrcweir             aBmpData.Stride      = 4*aBmpData.Width;
519cdf0e10cSrcweir             aBmpData.PixelFormat = PixelFormat32bppARGB;
520cdf0e10cSrcweir             aBmpData.Scan0       = aRes.getArray();
521cdf0e10cSrcweir 
522cdf0e10cSrcweir             // TODO(F1): Support more pixel formats natively
523cdf0e10cSrcweir 
524cdf0e10cSrcweir             // read data from bitmap
525cdf0e10cSrcweir             if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
526cdf0e10cSrcweir                                                 Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf,
527cdf0e10cSrcweir                                                 PixelFormat32bppARGB, // TODO(F1): Adapt to
528cdf0e10cSrcweir                                                                         // Graphics native
529cdf0e10cSrcweir                                                                         // format/change
530cdf0e10cSrcweir                                                                         // getMemoryLayout
531cdf0e10cSrcweir                                                 &aBmpData ) )
532cdf0e10cSrcweir             {
533cdf0e10cSrcweir                 // failed to lock, bail out
534cdf0e10cSrcweir                 return uno::Sequence< sal_Int8 >();
535cdf0e10cSrcweir             }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir             mpGDIPlusBitmap->UnlockBits( &aBmpData );
538cdf0e10cSrcweir 
539cdf0e10cSrcweir             return aRes;
540cdf0e10cSrcweir         }
541cdf0e10cSrcweir         else
542cdf0e10cSrcweir         {
543cdf0e10cSrcweir             sal_uInt32 nWidth = rect.X2-rect.X1;
544cdf0e10cSrcweir             sal_uInt32 nHeight = rect.Y2-rect.Y1;
545cdf0e10cSrcweir 
546cdf0e10cSrcweir             uno::Sequence< sal_Int8 > aRes(nWidth*nHeight*4);
547cdf0e10cSrcweir 
548cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
549cdf0e10cSrcweir             DDSURFACEDESC aSurfaceDesc;
550cdf0e10cSrcweir             rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
551cdf0e10cSrcweir             aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
552cdf0e10cSrcweir             const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
553cdf0e10cSrcweir 
554cdf0e10cSrcweir             // lock the directx surface to receive the pointer to the surface memory.
555cdf0e10cSrcweir             if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
556cdf0e10cSrcweir                 return uno::Sequence< sal_Int8 >();
557cdf0e10cSrcweir 
558cdf0e10cSrcweir             sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1);
559cdf0e10cSrcweir             sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray();
560cdf0e10cSrcweir             sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
561cdf0e10cSrcweir             for(sal_uInt32 y=0; y<nHeight; ++y)
562cdf0e10cSrcweir             {
563cdf0e10cSrcweir                 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
564cdf0e10cSrcweir                 pDst += nSegmentSizeInBytes;
565cdf0e10cSrcweir                 pSrc += aSurfaceDesc.lPitch;
566cdf0e10cSrcweir             }
567cdf0e10cSrcweir 
568cdf0e10cSrcweir             mpSurface->Unlock(NULL);
569cdf0e10cSrcweir #else
570cdf0e10cSrcweir             D3DLOCKED_RECT aLockedRect;
571cdf0e10cSrcweir             if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
572cdf0e10cSrcweir                 return uno::Sequence< sal_Int8 >();
573cdf0e10cSrcweir 
574cdf0e10cSrcweir             sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1);
575cdf0e10cSrcweir             sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray();
576cdf0e10cSrcweir             sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
577cdf0e10cSrcweir             for(sal_uInt32 y=0; y<nHeight; ++y)
578cdf0e10cSrcweir             {
579cdf0e10cSrcweir                 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
580cdf0e10cSrcweir                 pDst += nSegmentSizeInBytes;
581cdf0e10cSrcweir                 pSrc += aLockedRect.Pitch;
582cdf0e10cSrcweir             }
583cdf0e10cSrcweir 
584cdf0e10cSrcweir             mpSurface->UnlockRect();
585cdf0e10cSrcweir #endif
586cdf0e10cSrcweir             return aRes;
587cdf0e10cSrcweir         }
588cdf0e10cSrcweir     }
589cdf0e10cSrcweir 
590cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
591cdf0e10cSrcweir     // DXSurfaceBitmap::setData
592cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
593cdf0e10cSrcweir 
setData(const uno::Sequence<sal_Int8> & data,const rendering::IntegerBitmapLayout &,const geometry::IntegerRectangle2D & rect)594cdf0e10cSrcweir     void DXSurfaceBitmap::setData( const uno::Sequence< sal_Int8 >&      data,
595cdf0e10cSrcweir                                    const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
596cdf0e10cSrcweir                                    const geometry::IntegerRectangle2D&   rect )
597cdf0e10cSrcweir     {
598cdf0e10cSrcweir         if(hasAlpha())
599cdf0e10cSrcweir         {
600cdf0e10cSrcweir             const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
601cdf0e10cSrcweir 
602cdf0e10cSrcweir             Gdiplus::BitmapData aBmpData;
603cdf0e10cSrcweir             aBmpData.Width       = rect.X2-rect.X1;
604cdf0e10cSrcweir             aBmpData.Height      = rect.Y2-rect.Y1;
605cdf0e10cSrcweir             aBmpData.Stride      = 4*aBmpData.Width;
606cdf0e10cSrcweir             aBmpData.PixelFormat = PixelFormat32bppARGB;
607cdf0e10cSrcweir             aBmpData.Scan0       = (void*)data.getConstArray();
608cdf0e10cSrcweir 
609cdf0e10cSrcweir             // TODO(F1): Support more pixel formats natively
610cdf0e10cSrcweir 
611cdf0e10cSrcweir             if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
612cdf0e10cSrcweir                                                 Gdiplus::ImageLockModeWrite | Gdiplus::ImageLockModeUserInputBuf,
613cdf0e10cSrcweir                                                 PixelFormat32bppARGB, // TODO: Adapt to
614cdf0e10cSrcweir                                                                         // Graphics native
615cdf0e10cSrcweir                                                                         // format/change
616cdf0e10cSrcweir                                                                         // getMemoryLayout
617cdf0e10cSrcweir                                                 &aBmpData ) )
618cdf0e10cSrcweir             {
619cdf0e10cSrcweir                 throw uno::RuntimeException();
620cdf0e10cSrcweir             }
621cdf0e10cSrcweir 
622cdf0e10cSrcweir             // commit data to bitmap
623cdf0e10cSrcweir             mpGDIPlusBitmap->UnlockBits( &aBmpData );
624cdf0e10cSrcweir         }
625cdf0e10cSrcweir         else
626cdf0e10cSrcweir         {
627cdf0e10cSrcweir             sal_uInt32 nWidth = rect.X2-rect.X1;
628cdf0e10cSrcweir             sal_uInt32 nHeight = rect.Y2-rect.Y1;
629cdf0e10cSrcweir 
630cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
631cdf0e10cSrcweir             DDSURFACEDESC aSurfaceDesc;
632cdf0e10cSrcweir             rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
633cdf0e10cSrcweir             aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
634cdf0e10cSrcweir             const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY;
635cdf0e10cSrcweir 
636cdf0e10cSrcweir             // lock the directx surface to receive the pointer to the surface memory.
637cdf0e10cSrcweir             if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
638cdf0e10cSrcweir                 throw uno::RuntimeException();
639cdf0e10cSrcweir 
640cdf0e10cSrcweir             sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray();
641cdf0e10cSrcweir             sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1);
642cdf0e10cSrcweir             sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
643cdf0e10cSrcweir             for(sal_uInt32 y=0; y<nHeight; ++y)
644cdf0e10cSrcweir             {
645cdf0e10cSrcweir                 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
646cdf0e10cSrcweir                 pSrc += nSegmentSizeInBytes;
647cdf0e10cSrcweir                 pDst += aSurfaceDesc.lPitch;
648cdf0e10cSrcweir             }
649cdf0e10cSrcweir 
650cdf0e10cSrcweir             mpSurface->Unlock(NULL);
651cdf0e10cSrcweir #else
652cdf0e10cSrcweir             // lock the directx surface to receive the pointer to the surface memory.
653cdf0e10cSrcweir             D3DLOCKED_RECT aLockedRect;
654cdf0e10cSrcweir             if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
655cdf0e10cSrcweir                 throw uno::RuntimeException();
656cdf0e10cSrcweir 
657cdf0e10cSrcweir             sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray();
658cdf0e10cSrcweir             sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1);
659cdf0e10cSrcweir             sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
660cdf0e10cSrcweir             for(sal_uInt32 y=0; y<nHeight; ++y)
661cdf0e10cSrcweir             {
662cdf0e10cSrcweir                 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
663cdf0e10cSrcweir                 pSrc += nSegmentSizeInBytes;
664cdf0e10cSrcweir                 pDst += aLockedRect.Pitch;
665cdf0e10cSrcweir             }
666cdf0e10cSrcweir 
667cdf0e10cSrcweir             mpSurface->UnlockRect();
668cdf0e10cSrcweir #endif
669cdf0e10cSrcweir         }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir         mbIsSurfaceDirty = true;
672cdf0e10cSrcweir     }
673cdf0e10cSrcweir 
674cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
675cdf0e10cSrcweir     // DXSurfaceBitmap::setPixel
676cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
677cdf0e10cSrcweir 
setPixel(const uno::Sequence<sal_Int8> & color,const rendering::IntegerBitmapLayout &,const geometry::IntegerPoint2D & pos)678cdf0e10cSrcweir     void DXSurfaceBitmap::setPixel( const uno::Sequence< sal_Int8 >&      color,
679cdf0e10cSrcweir                                     const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
680cdf0e10cSrcweir                                     const geometry::IntegerPoint2D&       pos )
681cdf0e10cSrcweir     {
682cdf0e10cSrcweir         if(hasAlpha())
683cdf0e10cSrcweir         {
684cdf0e10cSrcweir             const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
685cdf0e10cSrcweir 
686cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
687cdf0e10cSrcweir                             "CanvasHelper::setPixel: X coordinate out of bounds" );
688cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
689cdf0e10cSrcweir                             "CanvasHelper::setPixel: Y coordinate out of bounds" );
690cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( color.getLength() > 3,
691cdf0e10cSrcweir                             "CanvasHelper::setPixel: not enough color components" );
692cdf0e10cSrcweir 
693cdf0e10cSrcweir             if( Gdiplus::Ok != mpGDIPlusBitmap->SetPixel( pos.X, pos.Y,
694cdf0e10cSrcweir                                                 Gdiplus::Color( tools::sequenceToArgb( color ))))
695cdf0e10cSrcweir             {
696cdf0e10cSrcweir                 throw uno::RuntimeException();
697cdf0e10cSrcweir             }
698cdf0e10cSrcweir         }
699cdf0e10cSrcweir         else
700cdf0e10cSrcweir         {
701cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(),
702cdf0e10cSrcweir                             "CanvasHelper::setPixel: X coordinate out of bounds" );
703cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(),
704cdf0e10cSrcweir                             "CanvasHelper::setPixel: Y coordinate out of bounds" );
705cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( color.getLength() > 3,
706cdf0e10cSrcweir                             "CanvasHelper::setPixel: not enough color components" );
707cdf0e10cSrcweir 
708cdf0e10cSrcweir             Gdiplus::Color aColor(tools::sequenceToArgb(color));
709cdf0e10cSrcweir 
710cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
711cdf0e10cSrcweir             DDSURFACEDESC aSurfaceDesc;
712cdf0e10cSrcweir             rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
713cdf0e10cSrcweir             aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
714cdf0e10cSrcweir             const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY;
715cdf0e10cSrcweir 
716cdf0e10cSrcweir             // lock the directx surface to receive the pointer to the surface memory.
717cdf0e10cSrcweir             if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
718cdf0e10cSrcweir                 throw uno::RuntimeException();
719cdf0e10cSrcweir 
720cdf0e10cSrcweir             sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X);
721cdf0e10cSrcweir             *pDst = aColor.GetValue();
722cdf0e10cSrcweir             mpSurface->Unlock(NULL);
723cdf0e10cSrcweir #else
724cdf0e10cSrcweir             // lock the directx surface to receive the pointer to the surface memory.
725cdf0e10cSrcweir             D3DLOCKED_RECT aLockedRect;
726cdf0e10cSrcweir             if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
727cdf0e10cSrcweir                 throw uno::RuntimeException();
728cdf0e10cSrcweir 
729cdf0e10cSrcweir             sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X);
730cdf0e10cSrcweir             *pDst = aColor.GetValue();
731cdf0e10cSrcweir             mpSurface->UnlockRect();
732cdf0e10cSrcweir #endif
733cdf0e10cSrcweir         }
734cdf0e10cSrcweir 
735cdf0e10cSrcweir         mbIsSurfaceDirty = true;
736cdf0e10cSrcweir     }
737cdf0e10cSrcweir 
738cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
739cdf0e10cSrcweir     // DXSurfaceBitmap::getPixel
740cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
741cdf0e10cSrcweir 
getPixel(rendering::IntegerBitmapLayout &,const geometry::IntegerPoint2D & pos)742cdf0e10cSrcweir     uno::Sequence< sal_Int8 > DXSurfaceBitmap::getPixel( rendering::IntegerBitmapLayout&   /*bitmapLayout*/,
743cdf0e10cSrcweir                                                          const geometry::IntegerPoint2D&   pos )
744cdf0e10cSrcweir     {
745cdf0e10cSrcweir         if(hasAlpha())
746cdf0e10cSrcweir         {
747cdf0e10cSrcweir             const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
748cdf0e10cSrcweir 
749cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
750cdf0e10cSrcweir                             "CanvasHelper::getPixel: X coordinate out of bounds" );
751cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
752cdf0e10cSrcweir                             "CanvasHelper::getPixel: Y coordinate out of bounds" );
753cdf0e10cSrcweir 
754cdf0e10cSrcweir             Gdiplus::Color aColor;
755cdf0e10cSrcweir 
756cdf0e10cSrcweir             if( Gdiplus::Ok != mpGDIPlusBitmap->GetPixel( pos.X, pos.Y, &aColor ) )
757cdf0e10cSrcweir                 return uno::Sequence< sal_Int8 >();
758cdf0e10cSrcweir 
759cdf0e10cSrcweir             return tools::argbToIntSequence(aColor.GetValue());
760cdf0e10cSrcweir         }
761cdf0e10cSrcweir         else
762cdf0e10cSrcweir         {
763cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(),
764cdf0e10cSrcweir                             "CanvasHelper::getPixel: X coordinate out of bounds" );
765cdf0e10cSrcweir             ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(),
766cdf0e10cSrcweir                             "CanvasHelper::getPixel: Y coordinate out of bounds" );
767cdf0e10cSrcweir 
768cdf0e10cSrcweir #if DIRECTX_VERSION < 0x0900
769cdf0e10cSrcweir             DDSURFACEDESC aSurfaceDesc;
770cdf0e10cSrcweir             rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
771cdf0e10cSrcweir             aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
772cdf0e10cSrcweir             const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
773cdf0e10cSrcweir 
774cdf0e10cSrcweir             // lock the directx surface to receive the pointer to the surface memory.
775cdf0e10cSrcweir             if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
776cdf0e10cSrcweir                 throw uno::RuntimeException();
777cdf0e10cSrcweir 
778cdf0e10cSrcweir             sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X);
779cdf0e10cSrcweir             Gdiplus::Color aColor(*pDst);
780cdf0e10cSrcweir             mpSurface->Unlock(NULL);
781cdf0e10cSrcweir #else
782cdf0e10cSrcweir             // lock the directx surface to receive the pointer to the surface memory.
783cdf0e10cSrcweir             D3DLOCKED_RECT aLockedRect;
784cdf0e10cSrcweir             if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
785cdf0e10cSrcweir                 throw uno::RuntimeException();
786cdf0e10cSrcweir 
787cdf0e10cSrcweir             sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X);
788cdf0e10cSrcweir             Gdiplus::Color aColor(*pDst);
789cdf0e10cSrcweir             mpSurface->UnlockRect();
790cdf0e10cSrcweir #endif
791cdf0e10cSrcweir 
792cdf0e10cSrcweir             return tools::argbToIntSequence(aColor.GetValue());
793cdf0e10cSrcweir         }
794cdf0e10cSrcweir     }
795cdf0e10cSrcweir 
796cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
797cdf0e10cSrcweir     // End of file
798cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////////////////
799cdf0e10cSrcweir }
800