CWS-TOOLING: integrate CWS os146
[LibreOffice.git] / canvas / source / directx / dx_surfacebitmap.cxx
blob258c10c4dd5ca39dbbc7aa7f204644ae461b631f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_canvas.hxx"
31 #include "dx_surfacebitmap.hxx"
32 #include "dx_impltools.hxx"
33 #include "dx_surfacegraphics.hxx"
34 #include "dx_graphicsprovider.hxx"
36 #include <canvas/debug.hxx>
37 #include <tools/diagnose_ex.h>
39 #include <basegfx/matrix/b2dhommatrix.hxx>
40 #include <basegfx/range/b2irange.hxx>
42 #if defined(DX_DEBUG_IMAGES)
43 # if OSL_DEBUG_LEVEL > 0
44 # include <imdebug.h>
45 # undef min
46 # undef max
47 # endif
48 #endif
50 using namespace ::com::sun::star;
52 namespace dxcanvas
54 namespace
56 //////////////////////////////////////////////////////////////////////////////////
57 // DXColorBuffer
58 //////////////////////////////////////////////////////////////////////////////////
60 struct DXColorBuffer : public canvas::IColorBuffer
62 public:
63 DXColorBuffer( const COMReference<surface_type>& rSurface,
64 const ::basegfx::B2IVector& rSize ) :
65 mpSurface(rSurface),
66 maSize(rSize),
67 mbAlpha(false)
71 // implementation of the 'IColorBuffer' interface
72 public:
74 virtual sal_uInt8* lock() const;
75 virtual void unlock() const;
76 virtual sal_uInt32 getWidth() const;
77 virtual sal_uInt32 getHeight() const;
78 virtual sal_uInt32 getStride() const;
79 virtual Format getFormat() const;
81 private:
83 ::basegfx::B2IVector maSize;
84 #if DIRECTX_VERSION < 0x0900
85 mutable DDSURFACEDESC aSurfaceDesc;
86 #else
87 mutable D3DLOCKED_RECT maLockedRect;
88 #endif
89 mutable COMReference<surface_type> mpSurface;
90 bool mbAlpha;
93 sal_uInt8* DXColorBuffer::lock() const
95 #if DIRECTX_VERSION < 0x0900
96 rtl_fillMemory((void *)&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
97 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
98 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
99 if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
100 return static_cast<sal_uInt8 *>(aSurfaceDesc.lpSurface);
101 #else
102 if(SUCCEEDED(mpSurface->LockRect(&maLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
103 return static_cast<sal_uInt8 *>(maLockedRect.pBits);
104 #endif
105 return NULL;
108 void DXColorBuffer::unlock() const
110 #if DIRECTX_VERSION < 0x0900
111 mpSurface->Unlock(NULL);
112 #else
113 mpSurface->UnlockRect();
114 #endif
117 sal_uInt32 DXColorBuffer::getWidth() const
119 return maSize.getX();
122 sal_uInt32 DXColorBuffer::getHeight() const
124 return maSize.getY();
127 sal_uInt32 DXColorBuffer::getStride() const
129 #if DIRECTX_VERSION < 0x0900
130 return aSurfaceDesc.lPitch;
131 #else
132 return maLockedRect.Pitch;
133 #endif
136 canvas::IColorBuffer::Format DXColorBuffer::getFormat() const
138 return canvas::IColorBuffer::FMT_X8R8G8B8;
141 //////////////////////////////////////////////////////////////////////////////////
142 // GDIColorBuffer
143 //////////////////////////////////////////////////////////////////////////////////
145 struct GDIColorBuffer : public canvas::IColorBuffer
147 public:
149 GDIColorBuffer( const BitmapSharedPtr& rSurface,
150 const ::basegfx::B2IVector& rSize ) :
151 mpGDIPlusBitmap(rSurface),
152 maSize(rSize),
153 mbAlpha(true)
157 // implementation of the 'IColorBuffer' interface
158 public:
160 virtual sal_uInt8* lock() const;
161 virtual void unlock() const;
162 virtual sal_uInt32 getWidth() const;
163 virtual sal_uInt32 getHeight() const;
164 virtual sal_uInt32 getStride() const;
165 virtual Format getFormat() const;
167 private:
169 ::basegfx::B2IVector maSize;
170 mutable Gdiplus::BitmapData aBmpData;
171 BitmapSharedPtr mpGDIPlusBitmap;
172 bool mbAlpha;
175 sal_uInt8* GDIColorBuffer::lock() const
177 aBmpData.Width = maSize.getX();
178 aBmpData.Height = maSize.getY();
179 aBmpData.Stride = 4*aBmpData.Width;
180 aBmpData.PixelFormat = PixelFormat32bppARGB;
181 aBmpData.Scan0 = NULL;
182 const Gdiplus::Rect aRect( 0,0,aBmpData.Width,aBmpData.Height );
183 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
184 Gdiplus::ImageLockModeRead,
185 PixelFormat32bppARGB,
186 &aBmpData ) )
188 return NULL;
191 return static_cast<sal_uInt8*>(aBmpData.Scan0);
194 void GDIColorBuffer::unlock() const
196 mpGDIPlusBitmap->UnlockBits( &aBmpData );
199 sal_uInt32 GDIColorBuffer::getWidth() const
201 return maSize.getX();
204 sal_uInt32 GDIColorBuffer::getHeight() const
206 return maSize.getY();
209 sal_uInt32 GDIColorBuffer::getStride() const
211 return aBmpData.Stride;
214 canvas::IColorBuffer::Format GDIColorBuffer::getFormat() const
216 return canvas::IColorBuffer::FMT_A8R8G8B8;
220 //////////////////////////////////////////////////////////////////////////////////
221 // DXSurfaceBitmap::DXSurfaceBitmap
222 //////////////////////////////////////////////////////////////////////////////////
224 DXSurfaceBitmap::DXSurfaceBitmap( const ::basegfx::B2IVector& rSize,
225 const canvas::ISurfaceProxyManagerSharedPtr& rMgr,
226 const IDXRenderModuleSharedPtr& rRenderModule,
227 bool bWithAlpha ) :
228 mpGdiPlusUser( GDIPlusUser::createInstance() ),
229 maSize(rSize),
230 mpRenderModule(rRenderModule),
231 mpSurfaceManager(rMgr),
232 mpSurfaceProxy(),
233 mpSurface(),
234 mpGDIPlusBitmap(),
235 mpGraphics(),
236 mpColorBuffer(),
237 mbIsSurfaceDirty(true),
238 mbAlpha(bWithAlpha)
240 init();
243 //////////////////////////////////////////////////////////////////////////////////
244 // DXSurfaceBitmap::getSize
245 //////////////////////////////////////////////////////////////////////////////////
247 ::basegfx::B2IVector DXSurfaceBitmap::getSize() const
249 return maSize;
252 //////////////////////////////////////////////////////////////////////////////////
253 // DXSurfaceBitmap::init
254 //////////////////////////////////////////////////////////////////////////////////
256 void DXSurfaceBitmap::init()
258 // create container for pixel data
259 if(mbAlpha)
261 mpGDIPlusBitmap.reset(
262 new Gdiplus::Bitmap(
263 maSize.getX(),
264 maSize.getY(),
265 PixelFormat32bppARGB
267 mpGraphics.reset( tools::createGraphicsFromBitmap(mpGDIPlusBitmap) );
269 // create the colorbuffer object, which is basically a simple
270 // wrapper around the directx surface. the colorbuffer is the
271 // interface which is used by the surfaceproxy to support any
272 // kind of underlying structure for the pixel data container.
273 mpColorBuffer.reset(new GDIColorBuffer(mpGDIPlusBitmap,maSize));
275 else
277 mpSurface = mpRenderModule->createSystemMemorySurface(maSize);
279 // create the colorbuffer object, which is basically a simple
280 // wrapper around the directx surface. the colorbuffer is the
281 // interface which is used by the surfaceproxy to support any
282 // kind of underlying structure for the pixel data container.
283 mpColorBuffer.reset(new DXColorBuffer(mpSurface,maSize));
286 // create a (possibly hardware accelerated) mirror surface.
287 mpSurfaceProxy = mpSurfaceManager->createSurfaceProxy(mpColorBuffer);
290 //////////////////////////////////////////////////////////////////////////////////
291 // DXSurfaceBitmap::resize
292 //////////////////////////////////////////////////////////////////////////////////
294 bool DXSurfaceBitmap::resize( const ::basegfx::B2IVector& rSize )
296 if(maSize != rSize)
298 maSize = rSize;
299 init();
302 return true;
305 //////////////////////////////////////////////////////////////////////////////////
306 // DXSurfaceBitmap::clear
307 //////////////////////////////////////////////////////////////////////////////////
309 void DXSurfaceBitmap::clear()
311 GraphicsSharedPtr pGraphics(getGraphics());
312 Gdiplus::Color transColor(255,0,0,0);
313 pGraphics->SetCompositingMode( Gdiplus::CompositingModeSourceCopy );
314 pGraphics->Clear( transColor );
317 //////////////////////////////////////////////////////////////////////////////////
318 // DXSurfaceBitmap::hasAlpha
319 //////////////////////////////////////////////////////////////////////////////////
321 bool DXSurfaceBitmap::hasAlpha() const
323 return mbAlpha;
326 //////////////////////////////////////////////////////////////////////////////////
327 // DXSurfaceBitmap::getGraphics
328 //////////////////////////////////////////////////////////////////////////////////
330 GraphicsSharedPtr DXSurfaceBitmap::getGraphics()
332 // since clients will most probably draw directly
333 // to the GDI+ bitmap, we need to mark it as dirty
334 // to ensure that the corrosponding dxsurface will
335 // be updated.
336 mbIsSurfaceDirty = true;
338 if(hasAlpha())
339 return mpGraphics;
340 else
341 return createSurfaceGraphics(mpSurface);
344 //////////////////////////////////////////////////////////////////////////////////
345 // DXSurfaceBitmap::getBitmap
346 //////////////////////////////////////////////////////////////////////////////////
348 BitmapSharedPtr DXSurfaceBitmap::getBitmap() const
350 if(hasAlpha())
351 return mpGDIPlusBitmap;
353 BitmapSharedPtr pResult;
355 #if DIRECTX_VERSION < 0x0900
356 DDSURFACEDESC aSurfaceDesc;
357 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
358 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
359 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
361 // lock the directx surface to receive the pointer to the surface memory.
362 if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
364 // decide about the format we pass the gdi+, the directx surface is always
365 // 32bit, either with or without alpha component.
366 Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB;
368 // construct a gdi+ bitmap from the raw pixel data.
369 pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(),
370 aSurfaceDesc.lPitch,
371 nFormat,
372 (BYTE *)aSurfaceDesc.lpSurface ));
374 // unlock the directx surface
375 mpSurface->Unlock(NULL);
377 #else
378 D3DLOCKED_RECT aLockedRect;
379 if(SUCCEEDED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
381 // decide about the format we pass the gdi+, the directx surface is always
382 // 32bit, either with or without alpha component.
383 Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB;
385 // construct a gdi+ bitmap from the raw pixel data.
386 pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(),
387 aLockedRect.Pitch,
388 nFormat,
389 (BYTE *)aLockedRect.pBits ));
391 mpSurface->UnlockRect();
393 #endif
395 return pResult;
398 //////////////////////////////////////////////////////////////////////////////////
399 // DXSurfaceBitmap::draw
400 //////////////////////////////////////////////////////////////////////////////////
402 bool DXSurfaceBitmap::draw( double fAlpha,
403 const ::basegfx::B2DPoint& rPos,
404 const ::basegfx::B2DPolyPolygon& rClipPoly,
405 const ::basegfx::B2DHomMatrix& rTransform )
407 if( mbIsSurfaceDirty )
409 mpSurfaceProxy->setColorBufferDirty();
410 mbIsSurfaceDirty = false;
413 return mpSurfaceProxy->draw( fAlpha, rPos, rClipPoly, rTransform );
416 //////////////////////////////////////////////////////////////////////////////////
417 // DXSurfaceBitmap::draw
418 //////////////////////////////////////////////////////////////////////////////////
420 bool DXSurfaceBitmap::draw( double fAlpha,
421 const ::basegfx::B2DPoint& rPos,
422 const ::basegfx::B2DRange& rArea,
423 const ::basegfx::B2DHomMatrix& rTransform )
425 if( mbIsSurfaceDirty )
427 mpSurfaceProxy->setColorBufferDirty();
428 mbIsSurfaceDirty = false;
431 return mpSurfaceProxy->draw( fAlpha, rPos, rArea, rTransform );
434 //////////////////////////////////////////////////////////////////////////////////
435 // DXSurfaceBitmap::draw
436 //////////////////////////////////////////////////////////////////////////////////
438 bool DXSurfaceBitmap::draw( double fAlpha,
439 const ::basegfx::B2DPoint& rPos,
440 const ::basegfx::B2DHomMatrix& rTransform )
442 if( mbIsSurfaceDirty )
444 mpSurfaceProxy->setColorBufferDirty();
445 mbIsSurfaceDirty = false;
448 return mpSurfaceProxy->draw( fAlpha, rPos, rTransform );
451 //////////////////////////////////////////////////////////////////////////////////
452 // DXSurfaceBitmap::draw
453 //////////////////////////////////////////////////////////////////////////////////
455 bool DXSurfaceBitmap::draw( const ::basegfx::B2IRange& rArea )
457 if( mbIsSurfaceDirty )
459 mpSurfaceProxy->setColorBufferDirty();
460 mbIsSurfaceDirty = false;
463 const double fAlpha(1.0);
464 const ::basegfx::B2DHomMatrix aTransform;
465 const ::basegfx::B2DRange aIEEEArea( rArea );
466 return mpSurfaceProxy->draw(fAlpha,
467 ::basegfx::B2DPoint(),
468 aIEEEArea,
469 aTransform);
472 //////////////////////////////////////////////////////////////////////////////////
473 // DXSurfaceBitmap::imageDebugger
474 //////////////////////////////////////////////////////////////////////////////////
475 #if defined(DX_DEBUG_IMAGES)
476 # if OSL_DEBUG_LEVEL > 0
477 void DXSurfaceBitmap::imageDebugger()
479 #if DIRECTX_VERSION < 0x0900
480 DDSURFACEDESC aSurfaceDesc;
481 rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 );
482 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
484 if( FAILED(mpSurface->Lock( NULL,
485 &aSurfaceDesc,
486 DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY,
487 NULL)) )
488 return;
490 imdebug("bgra w=%d h=%d %p", aSurfaceDesc.dwWidth, aSurfaceDesc.dwHeight, aSurfaceDesc.lpSurface);
492 mpSurface->Unlock(NULL);
493 #else
494 D3DLOCKED_RECT aLockedRect;
495 if( FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)) )
496 return;
498 imdebug("bgra w=%d h=%d %p", maSize.getX(),
499 maSize.getY(), aLockedRect.pBits);
500 mpSurface->UnlockRect();
501 #endif
503 # endif
504 #endif
506 //////////////////////////////////////////////////////////////////////////////////
507 // DXSurfaceBitmap::getData
508 //////////////////////////////////////////////////////////////////////////////////
510 uno::Sequence< sal_Int8 > DXSurfaceBitmap::getData( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
511 const geometry::IntegerRectangle2D& rect )
513 if(hasAlpha())
515 uno::Sequence< sal_Int8 > aRes( (rect.X2-rect.X1)*(rect.Y2-rect.Y1)*4 ); // TODO(F1): Be format-agnostic here
517 const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
519 Gdiplus::BitmapData aBmpData;
520 aBmpData.Width = rect.X2-rect.X1;
521 aBmpData.Height = rect.Y2-rect.Y1;
522 aBmpData.Stride = 4*aBmpData.Width;
523 aBmpData.PixelFormat = PixelFormat32bppARGB;
524 aBmpData.Scan0 = aRes.getArray();
526 // TODO(F1): Support more pixel formats natively
528 // read data from bitmap
529 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
530 Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf,
531 PixelFormat32bppARGB, // TODO(F1): Adapt to
532 // Graphics native
533 // format/change
534 // getMemoryLayout
535 &aBmpData ) )
537 // failed to lock, bail out
538 return uno::Sequence< sal_Int8 >();
541 mpGDIPlusBitmap->UnlockBits( &aBmpData );
543 return aRes;
545 else
547 sal_uInt32 nWidth = rect.X2-rect.X1;
548 sal_uInt32 nHeight = rect.Y2-rect.Y1;
550 uno::Sequence< sal_Int8 > aRes(nWidth*nHeight*4);
552 #if DIRECTX_VERSION < 0x0900
553 DDSURFACEDESC aSurfaceDesc;
554 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
555 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
556 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
558 // lock the directx surface to receive the pointer to the surface memory.
559 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
560 return uno::Sequence< sal_Int8 >();
562 sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1);
563 sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray();
564 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
565 for(sal_uInt32 y=0; y<nHeight; ++y)
567 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
568 pDst += nSegmentSizeInBytes;
569 pSrc += aSurfaceDesc.lPitch;
572 mpSurface->Unlock(NULL);
573 #else
574 D3DLOCKED_RECT aLockedRect;
575 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
576 return uno::Sequence< sal_Int8 >();
578 sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1);
579 sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray();
580 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
581 for(sal_uInt32 y=0; y<nHeight; ++y)
583 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
584 pDst += nSegmentSizeInBytes;
585 pSrc += aLockedRect.Pitch;
588 mpSurface->UnlockRect();
589 #endif
590 return aRes;
594 //////////////////////////////////////////////////////////////////////////////////
595 // DXSurfaceBitmap::setData
596 //////////////////////////////////////////////////////////////////////////////////
598 void DXSurfaceBitmap::setData( const uno::Sequence< sal_Int8 >& data,
599 const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
600 const geometry::IntegerRectangle2D& rect )
602 if(hasAlpha())
604 const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
606 Gdiplus::BitmapData aBmpData;
607 aBmpData.Width = rect.X2-rect.X1;
608 aBmpData.Height = rect.Y2-rect.Y1;
609 aBmpData.Stride = 4*aBmpData.Width;
610 aBmpData.PixelFormat = PixelFormat32bppARGB;
611 aBmpData.Scan0 = (void*)data.getConstArray();
613 // TODO(F1): Support more pixel formats natively
615 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
616 Gdiplus::ImageLockModeWrite | Gdiplus::ImageLockModeUserInputBuf,
617 PixelFormat32bppARGB, // TODO: Adapt to
618 // Graphics native
619 // format/change
620 // getMemoryLayout
621 &aBmpData ) )
623 throw uno::RuntimeException();
626 // commit data to bitmap
627 mpGDIPlusBitmap->UnlockBits( &aBmpData );
629 else
631 sal_uInt32 nWidth = rect.X2-rect.X1;
632 sal_uInt32 nHeight = rect.Y2-rect.Y1;
634 #if DIRECTX_VERSION < 0x0900
635 DDSURFACEDESC aSurfaceDesc;
636 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
637 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
638 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY;
640 // lock the directx surface to receive the pointer to the surface memory.
641 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
642 throw uno::RuntimeException();
644 sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray();
645 sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1);
646 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
647 for(sal_uInt32 y=0; y<nHeight; ++y)
649 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
650 pSrc += nSegmentSizeInBytes;
651 pDst += aSurfaceDesc.lPitch;
654 mpSurface->Unlock(NULL);
655 #else
656 // lock the directx surface to receive the pointer to the surface memory.
657 D3DLOCKED_RECT aLockedRect;
658 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
659 throw uno::RuntimeException();
661 sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray();
662 sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1);
663 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
664 for(sal_uInt32 y=0; y<nHeight; ++y)
666 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
667 pSrc += nSegmentSizeInBytes;
668 pDst += aLockedRect.Pitch;
671 mpSurface->UnlockRect();
672 #endif
675 mbIsSurfaceDirty = true;
678 //////////////////////////////////////////////////////////////////////////////////
679 // DXSurfaceBitmap::setPixel
680 //////////////////////////////////////////////////////////////////////////////////
682 void DXSurfaceBitmap::setPixel( const uno::Sequence< sal_Int8 >& color,
683 const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
684 const geometry::IntegerPoint2D& pos )
686 if(hasAlpha())
688 const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
690 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
691 "CanvasHelper::setPixel: X coordinate out of bounds" );
692 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
693 "CanvasHelper::setPixel: Y coordinate out of bounds" );
694 ENSURE_ARG_OR_THROW( color.getLength() > 3,
695 "CanvasHelper::setPixel: not enough color components" );
697 if( Gdiplus::Ok != mpGDIPlusBitmap->SetPixel( pos.X, pos.Y,
698 Gdiplus::Color( tools::sequenceToArgb( color ))))
700 throw uno::RuntimeException();
703 else
705 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(),
706 "CanvasHelper::setPixel: X coordinate out of bounds" );
707 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(),
708 "CanvasHelper::setPixel: Y coordinate out of bounds" );
709 ENSURE_ARG_OR_THROW( color.getLength() > 3,
710 "CanvasHelper::setPixel: not enough color components" );
712 Gdiplus::Color aColor(tools::sequenceToArgb(color));
714 #if DIRECTX_VERSION < 0x0900
715 DDSURFACEDESC aSurfaceDesc;
716 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
717 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
718 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY;
720 // lock the directx surface to receive the pointer to the surface memory.
721 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
722 throw uno::RuntimeException();
724 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X);
725 *pDst = aColor.GetValue();
726 mpSurface->Unlock(NULL);
727 #else
728 // lock the directx surface to receive the pointer to the surface memory.
729 D3DLOCKED_RECT aLockedRect;
730 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
731 throw uno::RuntimeException();
733 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X);
734 *pDst = aColor.GetValue();
735 mpSurface->UnlockRect();
736 #endif
739 mbIsSurfaceDirty = true;
742 //////////////////////////////////////////////////////////////////////////////////
743 // DXSurfaceBitmap::getPixel
744 //////////////////////////////////////////////////////////////////////////////////
746 uno::Sequence< sal_Int8 > DXSurfaceBitmap::getPixel( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
747 const geometry::IntegerPoint2D& pos )
749 if(hasAlpha())
751 const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
753 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
754 "CanvasHelper::getPixel: X coordinate out of bounds" );
755 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
756 "CanvasHelper::getPixel: Y coordinate out of bounds" );
758 Gdiplus::Color aColor;
760 if( Gdiplus::Ok != mpGDIPlusBitmap->GetPixel( pos.X, pos.Y, &aColor ) )
761 return uno::Sequence< sal_Int8 >();
763 return tools::argbToIntSequence(aColor.GetValue());
765 else
767 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(),
768 "CanvasHelper::getPixel: X coordinate out of bounds" );
769 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(),
770 "CanvasHelper::getPixel: Y coordinate out of bounds" );
772 #if DIRECTX_VERSION < 0x0900
773 DDSURFACEDESC aSurfaceDesc;
774 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
775 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
776 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
778 // lock the directx surface to receive the pointer to the surface memory.
779 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
780 throw uno::RuntimeException();
782 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X);
783 Gdiplus::Color aColor(*pDst);
784 mpSurface->Unlock(NULL);
785 #else
786 // lock the directx surface to receive the pointer to the surface memory.
787 D3DLOCKED_RECT aLockedRect;
788 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
789 throw uno::RuntimeException();
791 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X);
792 Gdiplus::Color aColor(*pDst);
793 mpSurface->UnlockRect();
794 #endif
796 return tools::argbToIntSequence(aColor.GetValue());
800 //////////////////////////////////////////////////////////////////////////////////
801 // End of file
802 //////////////////////////////////////////////////////////////////////////////////