merge the formfield patch from ooo-build
[ooovba.git] / canvas / source / directx / dx_surfacebitmap.cxx
blobd3597f6d1b6dbf7b88aa13ec5d050cdcf2dab6bc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dx_surfacebitmap.cxx,v $
10 * $Revision: 1.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_canvas.hxx"
34 #include "dx_surfacebitmap.hxx"
35 #include "dx_impltools.hxx"
36 #include "dx_surfacegraphics.hxx"
37 #include "dx_graphicsprovider.hxx"
39 #include <canvas/debug.hxx>
40 #include <tools/diagnose_ex.h>
42 #include <basegfx/matrix/b2dhommatrix.hxx>
43 #include <basegfx/range/b2irange.hxx>
45 #if defined(DX_DEBUG_IMAGES)
46 # if OSL_DEBUG_LEVEL > 0
47 # include <imdebug.h>
48 # undef min
49 # undef max
50 # endif
51 #endif
53 using namespace ::com::sun::star;
55 namespace dxcanvas
57 namespace
59 //////////////////////////////////////////////////////////////////////////////////
60 // DXColorBuffer
61 //////////////////////////////////////////////////////////////////////////////////
63 struct DXColorBuffer : public canvas::IColorBuffer
65 public:
66 DXColorBuffer( const COMReference<surface_type>& rSurface,
67 const ::basegfx::B2IVector& rSize ) :
68 mpSurface(rSurface),
69 maSize(rSize),
70 mbAlpha(false)
74 // implementation of the 'IColorBuffer' interface
75 public:
77 virtual sal_uInt8* lock() const;
78 virtual void unlock() const;
79 virtual sal_uInt32 getWidth() const;
80 virtual sal_uInt32 getHeight() const;
81 virtual sal_uInt32 getStride() const;
82 virtual Format getFormat() const;
84 private:
86 ::basegfx::B2IVector maSize;
87 #if DIRECTX_VERSION < 0x0900
88 mutable DDSURFACEDESC aSurfaceDesc;
89 #else
90 mutable D3DLOCKED_RECT maLockedRect;
91 #endif
92 mutable COMReference<surface_type> mpSurface;
93 bool mbAlpha;
96 sal_uInt8* DXColorBuffer::lock() const
98 #if DIRECTX_VERSION < 0x0900
99 rtl_fillMemory((void *)&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
100 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
101 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
102 if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
103 return static_cast<sal_uInt8 *>(aSurfaceDesc.lpSurface);
104 #else
105 if(SUCCEEDED(mpSurface->LockRect(&maLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
106 return static_cast<sal_uInt8 *>(maLockedRect.pBits);
107 #endif
108 return NULL;
111 void DXColorBuffer::unlock() const
113 #if DIRECTX_VERSION < 0x0900
114 mpSurface->Unlock(NULL);
115 #else
116 mpSurface->UnlockRect();
117 #endif
120 sal_uInt32 DXColorBuffer::getWidth() const
122 return maSize.getX();
125 sal_uInt32 DXColorBuffer::getHeight() const
127 return maSize.getY();
130 sal_uInt32 DXColorBuffer::getStride() const
132 #if DIRECTX_VERSION < 0x0900
133 return aSurfaceDesc.lPitch;
134 #else
135 return maLockedRect.Pitch;
136 #endif
139 canvas::IColorBuffer::Format DXColorBuffer::getFormat() const
141 return canvas::IColorBuffer::FMT_X8R8G8B8;
144 //////////////////////////////////////////////////////////////////////////////////
145 // GDIColorBuffer
146 //////////////////////////////////////////////////////////////////////////////////
148 struct GDIColorBuffer : public canvas::IColorBuffer
150 public:
152 GDIColorBuffer( const BitmapSharedPtr& rSurface,
153 const ::basegfx::B2IVector& rSize ) :
154 mpGDIPlusBitmap(rSurface),
155 maSize(rSize),
156 mbAlpha(true)
160 // implementation of the 'IColorBuffer' interface
161 public:
163 virtual sal_uInt8* lock() const;
164 virtual void unlock() const;
165 virtual sal_uInt32 getWidth() const;
166 virtual sal_uInt32 getHeight() const;
167 virtual sal_uInt32 getStride() const;
168 virtual Format getFormat() const;
170 private:
172 ::basegfx::B2IVector maSize;
173 mutable Gdiplus::BitmapData aBmpData;
174 BitmapSharedPtr mpGDIPlusBitmap;
175 bool mbAlpha;
178 sal_uInt8* GDIColorBuffer::lock() const
180 aBmpData.Width = maSize.getX();
181 aBmpData.Height = maSize.getY();
182 aBmpData.Stride = 4*aBmpData.Width;
183 aBmpData.PixelFormat = PixelFormat32bppARGB;
184 aBmpData.Scan0 = NULL;
185 const Gdiplus::Rect aRect( 0,0,aBmpData.Width,aBmpData.Height );
186 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
187 Gdiplus::ImageLockModeRead,
188 PixelFormat32bppARGB,
189 &aBmpData ) )
191 return NULL;
194 return static_cast<sal_uInt8*>(aBmpData.Scan0);
197 void GDIColorBuffer::unlock() const
199 mpGDIPlusBitmap->UnlockBits( &aBmpData );
202 sal_uInt32 GDIColorBuffer::getWidth() const
204 return maSize.getX();
207 sal_uInt32 GDIColorBuffer::getHeight() const
209 return maSize.getY();
212 sal_uInt32 GDIColorBuffer::getStride() const
214 return aBmpData.Stride;
217 canvas::IColorBuffer::Format GDIColorBuffer::getFormat() const
219 return canvas::IColorBuffer::FMT_A8R8G8B8;
223 //////////////////////////////////////////////////////////////////////////////////
224 // DXSurfaceBitmap::DXSurfaceBitmap
225 //////////////////////////////////////////////////////////////////////////////////
227 DXSurfaceBitmap::DXSurfaceBitmap( const ::basegfx::B2IVector& rSize,
228 const canvas::ISurfaceProxyManagerSharedPtr& rMgr,
229 const IDXRenderModuleSharedPtr& rRenderModule,
230 bool bWithAlpha ) :
231 mpGdiPlusUser( GDIPlusUser::createInstance() ),
232 maSize(rSize),
233 mpRenderModule(rRenderModule),
234 mpSurfaceManager(rMgr),
235 mpSurfaceProxy(),
236 mpSurface(),
237 mpGDIPlusBitmap(),
238 mpGraphics(),
239 mpColorBuffer(),
240 mbIsSurfaceDirty(true),
241 mbAlpha(bWithAlpha)
243 init();
246 //////////////////////////////////////////////////////////////////////////////////
247 // DXSurfaceBitmap::getSize
248 //////////////////////////////////////////////////////////////////////////////////
250 ::basegfx::B2IVector DXSurfaceBitmap::getSize() const
252 return maSize;
255 //////////////////////////////////////////////////////////////////////////////////
256 // DXSurfaceBitmap::init
257 //////////////////////////////////////////////////////////////////////////////////
259 void DXSurfaceBitmap::init()
261 // create container for pixel data
262 if(mbAlpha)
264 mpGDIPlusBitmap.reset(
265 new Gdiplus::Bitmap(
266 maSize.getX(),
267 maSize.getY(),
268 PixelFormat32bppARGB
270 mpGraphics.reset( tools::createGraphicsFromBitmap(mpGDIPlusBitmap) );
272 // create the colorbuffer object, which is basically a simple
273 // wrapper around the directx surface. the colorbuffer is the
274 // interface which is used by the surfaceproxy to support any
275 // kind of underlying structure for the pixel data container.
276 mpColorBuffer.reset(new GDIColorBuffer(mpGDIPlusBitmap,maSize));
278 else
280 mpSurface = mpRenderModule->createSystemMemorySurface(maSize);
282 // create the colorbuffer object, which is basically a simple
283 // wrapper around the directx surface. the colorbuffer is the
284 // interface which is used by the surfaceproxy to support any
285 // kind of underlying structure for the pixel data container.
286 mpColorBuffer.reset(new DXColorBuffer(mpSurface,maSize));
289 // create a (possibly hardware accelerated) mirror surface.
290 mpSurfaceProxy = mpSurfaceManager->createSurfaceProxy(mpColorBuffer);
293 //////////////////////////////////////////////////////////////////////////////////
294 // DXSurfaceBitmap::resize
295 //////////////////////////////////////////////////////////////////////////////////
297 bool DXSurfaceBitmap::resize( const ::basegfx::B2IVector& rSize )
299 if(maSize != rSize)
301 maSize = rSize;
302 init();
305 return true;
308 //////////////////////////////////////////////////////////////////////////////////
309 // DXSurfaceBitmap::clear
310 //////////////////////////////////////////////////////////////////////////////////
312 void DXSurfaceBitmap::clear()
314 GraphicsSharedPtr pGraphics(getGraphics());
315 Gdiplus::Color transColor(255,0,0,0);
316 pGraphics->SetCompositingMode( Gdiplus::CompositingModeSourceCopy );
317 pGraphics->Clear( transColor );
320 //////////////////////////////////////////////////////////////////////////////////
321 // DXSurfaceBitmap::hasAlpha
322 //////////////////////////////////////////////////////////////////////////////////
324 bool DXSurfaceBitmap::hasAlpha() const
326 return mbAlpha;
329 //////////////////////////////////////////////////////////////////////////////////
330 // DXSurfaceBitmap::getGraphics
331 //////////////////////////////////////////////////////////////////////////////////
333 GraphicsSharedPtr DXSurfaceBitmap::getGraphics()
335 // since clients will most probably draw directly
336 // to the GDI+ bitmap, we need to mark it as dirty
337 // to ensure that the corrosponding dxsurface will
338 // be updated.
339 mbIsSurfaceDirty = true;
341 if(hasAlpha())
342 return mpGraphics;
343 else
344 return createSurfaceGraphics(mpSurface);
347 //////////////////////////////////////////////////////////////////////////////////
348 // DXSurfaceBitmap::getBitmap
349 //////////////////////////////////////////////////////////////////////////////////
351 BitmapSharedPtr DXSurfaceBitmap::getBitmap() const
353 if(hasAlpha())
354 return mpGDIPlusBitmap;
356 BitmapSharedPtr pResult;
358 #if DIRECTX_VERSION < 0x0900
359 DDSURFACEDESC aSurfaceDesc;
360 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
361 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
362 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
364 // lock the directx surface to receive the pointer to the surface memory.
365 if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
367 // decide about the format we pass the gdi+, the directx surface is always
368 // 32bit, either with or without alpha component.
369 Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB;
371 // construct a gdi+ bitmap from the raw pixel data.
372 pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(),
373 aSurfaceDesc.lPitch,
374 nFormat,
375 (BYTE *)aSurfaceDesc.lpSurface ));
377 // unlock the directx surface
378 mpSurface->Unlock(NULL);
380 #else
381 D3DLOCKED_RECT aLockedRect;
382 if(SUCCEEDED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
384 // decide about the format we pass the gdi+, the directx surface is always
385 // 32bit, either with or without alpha component.
386 Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB;
388 // construct a gdi+ bitmap from the raw pixel data.
389 pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(),
390 aLockedRect.Pitch,
391 nFormat,
392 (BYTE *)aLockedRect.pBits ));
394 mpSurface->UnlockRect();
396 #endif
398 return pResult;
401 //////////////////////////////////////////////////////////////////////////////////
402 // DXSurfaceBitmap::draw
403 //////////////////////////////////////////////////////////////////////////////////
405 bool DXSurfaceBitmap::draw( double fAlpha,
406 const ::basegfx::B2DPoint& rPos,
407 const ::basegfx::B2DPolyPolygon& rClipPoly,
408 const ::basegfx::B2DHomMatrix& rTransform )
410 if( mbIsSurfaceDirty )
412 mpSurfaceProxy->setColorBufferDirty();
413 mbIsSurfaceDirty = false;
416 return mpSurfaceProxy->draw( fAlpha, rPos, rClipPoly, rTransform );
419 //////////////////////////////////////////////////////////////////////////////////
420 // DXSurfaceBitmap::draw
421 //////////////////////////////////////////////////////////////////////////////////
423 bool DXSurfaceBitmap::draw( double fAlpha,
424 const ::basegfx::B2DPoint& rPos,
425 const ::basegfx::B2DRange& rArea,
426 const ::basegfx::B2DHomMatrix& rTransform )
428 if( mbIsSurfaceDirty )
430 mpSurfaceProxy->setColorBufferDirty();
431 mbIsSurfaceDirty = false;
434 return mpSurfaceProxy->draw( fAlpha, rPos, rArea, rTransform );
437 //////////////////////////////////////////////////////////////////////////////////
438 // DXSurfaceBitmap::draw
439 //////////////////////////////////////////////////////////////////////////////////
441 bool DXSurfaceBitmap::draw( double fAlpha,
442 const ::basegfx::B2DPoint& rPos,
443 const ::basegfx::B2DHomMatrix& rTransform )
445 if( mbIsSurfaceDirty )
447 mpSurfaceProxy->setColorBufferDirty();
448 mbIsSurfaceDirty = false;
451 return mpSurfaceProxy->draw( fAlpha, rPos, rTransform );
454 //////////////////////////////////////////////////////////////////////////////////
455 // DXSurfaceBitmap::draw
456 //////////////////////////////////////////////////////////////////////////////////
458 bool DXSurfaceBitmap::draw( const ::basegfx::B2IRange& rArea )
460 if( mbIsSurfaceDirty )
462 mpSurfaceProxy->setColorBufferDirty();
463 mbIsSurfaceDirty = false;
466 const double fAlpha(1.0);
467 const ::basegfx::B2DHomMatrix aTransform;
468 const ::basegfx::B2DRange aIEEEArea( rArea );
469 return mpSurfaceProxy->draw(fAlpha,
470 ::basegfx::B2DPoint(),
471 aIEEEArea,
472 aTransform);
475 //////////////////////////////////////////////////////////////////////////////////
476 // DXSurfaceBitmap::imageDebugger
477 //////////////////////////////////////////////////////////////////////////////////
478 #if defined(DX_DEBUG_IMAGES)
479 # if OSL_DEBUG_LEVEL > 0
480 void DXSurfaceBitmap::imageDebugger()
482 #if DIRECTX_VERSION < 0x0900
483 DDSURFACEDESC aSurfaceDesc;
484 rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 );
485 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
487 if( FAILED(mpSurface->Lock( NULL,
488 &aSurfaceDesc,
489 DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY,
490 NULL)) )
491 return;
493 imdebug("bgra w=%d h=%d %p", aSurfaceDesc.dwWidth, aSurfaceDesc.dwHeight, aSurfaceDesc.lpSurface);
495 mpSurface->Unlock(NULL);
496 #else
497 D3DLOCKED_RECT aLockedRect;
498 if( FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)) )
499 return;
501 imdebug("bgra w=%d h=%d %p", maSize.getX(),
502 maSize.getY(), aLockedRect.pBits);
503 mpSurface->UnlockRect();
504 #endif
506 # endif
507 #endif
509 //////////////////////////////////////////////////////////////////////////////////
510 // DXSurfaceBitmap::getData
511 //////////////////////////////////////////////////////////////////////////////////
513 uno::Sequence< sal_Int8 > DXSurfaceBitmap::getData( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
514 const geometry::IntegerRectangle2D& rect )
516 if(hasAlpha())
518 uno::Sequence< sal_Int8 > aRes( (rect.X2-rect.X1)*(rect.Y2-rect.Y1)*4 ); // TODO(F1): Be format-agnostic here
520 const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
522 Gdiplus::BitmapData aBmpData;
523 aBmpData.Width = rect.X2-rect.X1;
524 aBmpData.Height = rect.Y2-rect.Y1;
525 aBmpData.Stride = 4*aBmpData.Width;
526 aBmpData.PixelFormat = PixelFormat32bppARGB;
527 aBmpData.Scan0 = aRes.getArray();
529 // TODO(F1): Support more pixel formats natively
531 // read data from bitmap
532 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
533 Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf,
534 PixelFormat32bppARGB, // TODO(F1): Adapt to
535 // Graphics native
536 // format/change
537 // getMemoryLayout
538 &aBmpData ) )
540 // failed to lock, bail out
541 return uno::Sequence< sal_Int8 >();
544 mpGDIPlusBitmap->UnlockBits( &aBmpData );
546 return aRes;
548 else
550 sal_uInt32 nWidth = rect.X2-rect.X1;
551 sal_uInt32 nHeight = rect.Y2-rect.Y1;
553 uno::Sequence< sal_Int8 > aRes(nWidth*nHeight*4);
555 #if DIRECTX_VERSION < 0x0900
556 DDSURFACEDESC aSurfaceDesc;
557 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
558 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
559 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
561 // lock the directx surface to receive the pointer to the surface memory.
562 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
563 return uno::Sequence< sal_Int8 >();
565 sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1);
566 sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray();
567 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
568 for(sal_uInt32 y=0; y<nHeight; ++y)
570 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
571 pDst += nSegmentSizeInBytes;
572 pSrc += aSurfaceDesc.lPitch;
575 mpSurface->Unlock(NULL);
576 #else
577 D3DLOCKED_RECT aLockedRect;
578 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
579 return uno::Sequence< sal_Int8 >();
581 sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1);
582 sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray();
583 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
584 for(sal_uInt32 y=0; y<nHeight; ++y)
586 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
587 pDst += nSegmentSizeInBytes;
588 pSrc += aLockedRect.Pitch;
591 mpSurface->UnlockRect();
592 #endif
593 return aRes;
597 //////////////////////////////////////////////////////////////////////////////////
598 // DXSurfaceBitmap::setData
599 //////////////////////////////////////////////////////////////////////////////////
601 void DXSurfaceBitmap::setData( const uno::Sequence< sal_Int8 >& data,
602 const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
603 const geometry::IntegerRectangle2D& rect )
605 if(hasAlpha())
607 const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
609 Gdiplus::BitmapData aBmpData;
610 aBmpData.Width = rect.X2-rect.X1;
611 aBmpData.Height = rect.Y2-rect.Y1;
612 aBmpData.Stride = 4*aBmpData.Width;
613 aBmpData.PixelFormat = PixelFormat32bppARGB;
614 aBmpData.Scan0 = (void*)data.getConstArray();
616 // TODO(F1): Support more pixel formats natively
618 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
619 Gdiplus::ImageLockModeWrite | Gdiplus::ImageLockModeUserInputBuf,
620 PixelFormat32bppARGB, // TODO: Adapt to
621 // Graphics native
622 // format/change
623 // getMemoryLayout
624 &aBmpData ) )
626 throw uno::RuntimeException();
629 // commit data to bitmap
630 mpGDIPlusBitmap->UnlockBits( &aBmpData );
632 else
634 sal_uInt32 nWidth = rect.X2-rect.X1;
635 sal_uInt32 nHeight = rect.Y2-rect.Y1;
637 #if DIRECTX_VERSION < 0x0900
638 DDSURFACEDESC aSurfaceDesc;
639 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
640 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
641 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY;
643 // lock the directx surface to receive the pointer to the surface memory.
644 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
645 throw uno::RuntimeException();
647 sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray();
648 sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1);
649 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
650 for(sal_uInt32 y=0; y<nHeight; ++y)
652 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
653 pSrc += nSegmentSizeInBytes;
654 pDst += aSurfaceDesc.lPitch;
657 mpSurface->Unlock(NULL);
658 #else
659 // lock the directx surface to receive the pointer to the surface memory.
660 D3DLOCKED_RECT aLockedRect;
661 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
662 throw uno::RuntimeException();
664 sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray();
665 sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1);
666 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
667 for(sal_uInt32 y=0; y<nHeight; ++y)
669 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes);
670 pSrc += nSegmentSizeInBytes;
671 pDst += aLockedRect.Pitch;
674 mpSurface->UnlockRect();
675 #endif
678 mbIsSurfaceDirty = true;
681 //////////////////////////////////////////////////////////////////////////////////
682 // DXSurfaceBitmap::setPixel
683 //////////////////////////////////////////////////////////////////////////////////
685 void DXSurfaceBitmap::setPixel( const uno::Sequence< sal_Int8 >& color,
686 const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
687 const geometry::IntegerPoint2D& pos )
689 if(hasAlpha())
691 const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
693 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
694 "CanvasHelper::setPixel: X coordinate out of bounds" );
695 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
696 "CanvasHelper::setPixel: Y coordinate out of bounds" );
697 ENSURE_ARG_OR_THROW( color.getLength() > 3,
698 "CanvasHelper::setPixel: not enough color components" );
700 if( Gdiplus::Ok != mpGDIPlusBitmap->SetPixel( pos.X, pos.Y,
701 Gdiplus::Color( tools::sequenceToArgb( color ))))
703 throw uno::RuntimeException();
706 else
708 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(),
709 "CanvasHelper::setPixel: X coordinate out of bounds" );
710 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(),
711 "CanvasHelper::setPixel: Y coordinate out of bounds" );
712 ENSURE_ARG_OR_THROW( color.getLength() > 3,
713 "CanvasHelper::setPixel: not enough color components" );
715 Gdiplus::Color aColor(tools::sequenceToArgb(color));
717 #if DIRECTX_VERSION < 0x0900
718 DDSURFACEDESC aSurfaceDesc;
719 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
720 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
721 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY;
723 // lock the directx surface to receive the pointer to the surface memory.
724 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
725 throw uno::RuntimeException();
727 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X);
728 *pDst = aColor.GetValue();
729 mpSurface->Unlock(NULL);
730 #else
731 // lock the directx surface to receive the pointer to the surface memory.
732 D3DLOCKED_RECT aLockedRect;
733 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
734 throw uno::RuntimeException();
736 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X);
737 *pDst = aColor.GetValue();
738 mpSurface->UnlockRect();
739 #endif
742 mbIsSurfaceDirty = true;
745 //////////////////////////////////////////////////////////////////////////////////
746 // DXSurfaceBitmap::getPixel
747 //////////////////////////////////////////////////////////////////////////////////
749 uno::Sequence< sal_Int8 > DXSurfaceBitmap::getPixel( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
750 const geometry::IntegerPoint2D& pos )
752 if(hasAlpha())
754 const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
756 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
757 "CanvasHelper::getPixel: X coordinate out of bounds" );
758 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
759 "CanvasHelper::getPixel: Y coordinate out of bounds" );
761 Gdiplus::Color aColor;
763 if( Gdiplus::Ok != mpGDIPlusBitmap->GetPixel( pos.X, pos.Y, &aColor ) )
764 return uno::Sequence< sal_Int8 >();
766 return tools::argbToIntSequence(aColor.GetValue());
768 else
770 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(),
771 "CanvasHelper::getPixel: X coordinate out of bounds" );
772 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(),
773 "CanvasHelper::getPixel: Y coordinate out of bounds" );
775 #if DIRECTX_VERSION < 0x0900
776 DDSURFACEDESC aSurfaceDesc;
777 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0);
778 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
779 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
781 // lock the directx surface to receive the pointer to the surface memory.
782 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
783 throw uno::RuntimeException();
785 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X);
786 Gdiplus::Color aColor(*pDst);
787 mpSurface->Unlock(NULL);
788 #else
789 // lock the directx surface to receive the pointer to the surface memory.
790 D3DLOCKED_RECT aLockedRect;
791 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
792 throw uno::RuntimeException();
794 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X);
795 Gdiplus::Color aColor(*pDst);
796 mpSurface->UnlockRect();
797 #endif
799 return tools::argbToIntSequence(aColor.GetValue());
803 //////////////////////////////////////////////////////////////////////////////////
804 // End of file
805 //////////////////////////////////////////////////////////////////////////////////