update credits
[LibreOffice.git] / canvas / source / directx / dx_surfacebitmap.cxx
blobc45d5af9fa79d007e4549fc73cb6e30af208b663
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
22 #include "dx_surfacebitmap.hxx"
23 #include "dx_impltools.hxx"
24 #include "dx_surfacegraphics.hxx"
25 #include "dx_graphicsprovider.hxx"
27 #include <canvas/debug.hxx>
28 #include <tools/diagnose_ex.h>
30 #include <basegfx/matrix/b2dhommatrix.hxx>
31 #include <basegfx/range/b2irange.hxx>
33 #if defined(DX_DEBUG_IMAGES)
34 # if OSL_DEBUG_LEVEL > 0
35 # include <imdebug.h>
36 # undef min
37 # undef max
38 # endif
39 #endif
41 using namespace ::com::sun::star;
43 namespace dxcanvas
45 namespace
47 //////////////////////////////////////////////////////////////////////////////////
48 // DXColorBuffer
49 //////////////////////////////////////////////////////////////////////////////////
51 struct DXColorBuffer : public canvas::IColorBuffer
53 public:
54 DXColorBuffer( const COMReference<surface_type>& rSurface,
55 const ::basegfx::B2IVector& rSize ) :
56 mpSurface(rSurface),
57 maSize(rSize),
58 mbAlpha(false)
62 // implementation of the 'IColorBuffer' interface
63 public:
65 virtual sal_uInt8* lock() const;
66 virtual void unlock() const;
67 virtual sal_uInt32 getWidth() const;
68 virtual sal_uInt32 getHeight() const;
69 virtual sal_uInt32 getStride() const;
70 virtual Format getFormat() const;
72 private:
74 ::basegfx::B2IVector maSize;
75 #if DIRECTX_VERSION < 0x0900
76 mutable DDSURFACEDESC aSurfaceDesc;
77 #else
78 mutable D3DLOCKED_RECT maLockedRect;
79 #endif
80 mutable COMReference<surface_type> mpSurface;
81 bool mbAlpha;
84 sal_uInt8* DXColorBuffer::lock() const
86 #if DIRECTX_VERSION < 0x0900
87 memset((void *)&aSurfaceDesc, 0, sizeof(DDSURFACEDESC));
88 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
89 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
90 if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
91 return static_cast<sal_uInt8 *>(aSurfaceDesc.lpSurface);
92 #else
93 if(SUCCEEDED(mpSurface->LockRect(&maLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
94 return static_cast<sal_uInt8 *>(maLockedRect.pBits);
95 #endif
96 return NULL;
99 void DXColorBuffer::unlock() const
101 #if DIRECTX_VERSION < 0x0900
102 mpSurface->Unlock(NULL);
103 #else
104 mpSurface->UnlockRect();
105 #endif
108 sal_uInt32 DXColorBuffer::getWidth() const
110 return maSize.getX();
113 sal_uInt32 DXColorBuffer::getHeight() const
115 return maSize.getY();
118 sal_uInt32 DXColorBuffer::getStride() const
120 #if DIRECTX_VERSION < 0x0900
121 return aSurfaceDesc.lPitch;
122 #else
123 return maLockedRect.Pitch;
124 #endif
127 canvas::IColorBuffer::Format DXColorBuffer::getFormat() const
129 return canvas::IColorBuffer::FMT_X8R8G8B8;
132 //////////////////////////////////////////////////////////////////////////////////
133 // GDIColorBuffer
134 //////////////////////////////////////////////////////////////////////////////////
136 struct GDIColorBuffer : public canvas::IColorBuffer
138 public:
140 GDIColorBuffer( const BitmapSharedPtr& rSurface,
141 const ::basegfx::B2IVector& rSize ) :
142 mpGDIPlusBitmap(rSurface),
143 maSize(rSize),
144 mbAlpha(true)
148 // implementation of the 'IColorBuffer' interface
149 public:
151 virtual sal_uInt8* lock() const;
152 virtual void unlock() const;
153 virtual sal_uInt32 getWidth() const;
154 virtual sal_uInt32 getHeight() const;
155 virtual sal_uInt32 getStride() const;
156 virtual Format getFormat() const;
158 private:
160 ::basegfx::B2IVector maSize;
161 mutable Gdiplus::BitmapData aBmpData;
162 BitmapSharedPtr mpGDIPlusBitmap;
163 bool mbAlpha;
166 sal_uInt8* GDIColorBuffer::lock() const
168 aBmpData.Width = maSize.getX();
169 aBmpData.Height = maSize.getY();
170 aBmpData.Stride = 4*aBmpData.Width;
171 aBmpData.PixelFormat = PixelFormat32bppARGB;
172 aBmpData.Scan0 = NULL;
173 const Gdiplus::Rect aRect( 0,0,aBmpData.Width,aBmpData.Height );
174 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
175 Gdiplus::ImageLockModeRead,
176 PixelFormat32bppARGB,
177 &aBmpData ) )
179 return NULL;
182 return static_cast<sal_uInt8*>(aBmpData.Scan0);
185 void GDIColorBuffer::unlock() const
187 mpGDIPlusBitmap->UnlockBits( &aBmpData );
190 sal_uInt32 GDIColorBuffer::getWidth() const
192 return maSize.getX();
195 sal_uInt32 GDIColorBuffer::getHeight() const
197 return maSize.getY();
200 sal_uInt32 GDIColorBuffer::getStride() const
202 return aBmpData.Stride;
205 canvas::IColorBuffer::Format GDIColorBuffer::getFormat() const
207 return canvas::IColorBuffer::FMT_A8R8G8B8;
211 //////////////////////////////////////////////////////////////////////////////////
212 // DXSurfaceBitmap::DXSurfaceBitmap
213 //////////////////////////////////////////////////////////////////////////////////
215 DXSurfaceBitmap::DXSurfaceBitmap( const ::basegfx::B2IVector& rSize,
216 const canvas::ISurfaceProxyManagerSharedPtr& rMgr,
217 const IDXRenderModuleSharedPtr& rRenderModule,
218 bool bWithAlpha ) :
219 mpGdiPlusUser( GDIPlusUser::createInstance() ),
220 maSize(rSize),
221 mpRenderModule(rRenderModule),
222 mpSurfaceManager(rMgr),
223 mpSurfaceProxy(),
224 mpSurface(),
225 mpGDIPlusBitmap(),
226 mpGraphics(),
227 mpColorBuffer(),
228 mbIsSurfaceDirty(true),
229 mbAlpha(bWithAlpha)
231 init();
234 //////////////////////////////////////////////////////////////////////////////////
235 // DXSurfaceBitmap::getSize
236 //////////////////////////////////////////////////////////////////////////////////
238 ::basegfx::B2IVector DXSurfaceBitmap::getSize() const
240 return maSize;
243 //////////////////////////////////////////////////////////////////////////////////
244 // DXSurfaceBitmap::init
245 //////////////////////////////////////////////////////////////////////////////////
247 void DXSurfaceBitmap::init()
249 // create container for pixel data
250 if(mbAlpha)
252 mpGDIPlusBitmap.reset(
253 new Gdiplus::Bitmap(
254 maSize.getX(),
255 maSize.getY(),
256 PixelFormat32bppARGB
258 mpGraphics.reset( tools::createGraphicsFromBitmap(mpGDIPlusBitmap) );
260 // create the colorbuffer object, which is basically a simple
261 // wrapper around the directx surface. the colorbuffer is the
262 // interface which is used by the surfaceproxy to support any
263 // kind of underlying structure for the pixel data container.
264 mpColorBuffer.reset(new GDIColorBuffer(mpGDIPlusBitmap,maSize));
266 else
268 mpSurface = mpRenderModule->createSystemMemorySurface(maSize);
270 // create the colorbuffer object, which is basically a simple
271 // wrapper around the directx surface. the colorbuffer is the
272 // interface which is used by the surfaceproxy to support any
273 // kind of underlying structure for the pixel data container.
274 mpColorBuffer.reset(new DXColorBuffer(mpSurface,maSize));
277 // create a (possibly hardware accelerated) mirror surface.
278 mpSurfaceProxy = mpSurfaceManager->createSurfaceProxy(mpColorBuffer);
281 //////////////////////////////////////////////////////////////////////////////////
282 // DXSurfaceBitmap::resize
283 //////////////////////////////////////////////////////////////////////////////////
285 bool DXSurfaceBitmap::resize( const ::basegfx::B2IVector& rSize )
287 if(maSize != rSize)
289 maSize = rSize;
290 init();
293 return true;
296 //////////////////////////////////////////////////////////////////////////////////
297 // DXSurfaceBitmap::clear
298 //////////////////////////////////////////////////////////////////////////////////
300 void DXSurfaceBitmap::clear()
302 GraphicsSharedPtr pGraphics(getGraphics());
303 Gdiplus::Color transColor(255,0,0,0);
304 pGraphics->SetCompositingMode( Gdiplus::CompositingModeSourceCopy );
305 pGraphics->Clear( transColor );
308 //////////////////////////////////////////////////////////////////////////////////
309 // DXSurfaceBitmap::hasAlpha
310 //////////////////////////////////////////////////////////////////////////////////
312 bool DXSurfaceBitmap::hasAlpha() const
314 return mbAlpha;
317 //////////////////////////////////////////////////////////////////////////////////
318 // DXSurfaceBitmap::getGraphics
319 //////////////////////////////////////////////////////////////////////////////////
321 GraphicsSharedPtr DXSurfaceBitmap::getGraphics()
323 // since clients will most probably draw directly
324 // to the GDI+ bitmap, we need to mark it as dirty
325 // to ensure that the corrosponding dxsurface will
326 // be updated.
327 mbIsSurfaceDirty = true;
329 if(hasAlpha())
330 return mpGraphics;
331 else
332 return createSurfaceGraphics(mpSurface);
335 //////////////////////////////////////////////////////////////////////////////////
336 // DXSurfaceBitmap::getBitmap
337 //////////////////////////////////////////////////////////////////////////////////
339 BitmapSharedPtr DXSurfaceBitmap::getBitmap() const
341 if(hasAlpha())
342 return mpGDIPlusBitmap;
344 BitmapSharedPtr pResult;
346 #if DIRECTX_VERSION < 0x0900
347 DDSURFACEDESC aSurfaceDesc;
348 memset(&aSurfaceDesc, 0, sizeof(DDSURFACEDESC));
349 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
350 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
352 // lock the directx surface to receive the pointer to the surface memory.
353 if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
355 // decide about the format we pass the gdi+, the directx surface is always
356 // 32bit, either with or without alpha component.
357 Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB;
359 // construct a gdi+ bitmap from the raw pixel data.
360 pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(),
361 aSurfaceDesc.lPitch,
362 nFormat,
363 (BYTE *)aSurfaceDesc.lpSurface ));
365 // unlock the directx surface
366 mpSurface->Unlock(NULL);
368 #else
369 D3DLOCKED_RECT aLockedRect;
370 if(SUCCEEDED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
372 // decide about the format we pass the gdi+, the directx surface is always
373 // 32bit, either with or without alpha component.
374 Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB;
376 // construct a gdi+ bitmap from the raw pixel data.
377 pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(),
378 aLockedRect.Pitch,
379 nFormat,
380 (BYTE *)aLockedRect.pBits ));
382 mpSurface->UnlockRect();
384 #endif
386 return pResult;
389 //////////////////////////////////////////////////////////////////////////////////
390 // DXSurfaceBitmap::draw
391 //////////////////////////////////////////////////////////////////////////////////
393 bool DXSurfaceBitmap::draw( double fAlpha,
394 const ::basegfx::B2DPoint& rPos,
395 const ::basegfx::B2DPolyPolygon& rClipPoly,
396 const ::basegfx::B2DHomMatrix& rTransform )
398 if( mbIsSurfaceDirty )
400 mpSurfaceProxy->setColorBufferDirty();
401 mbIsSurfaceDirty = false;
404 return mpSurfaceProxy->draw( fAlpha, rPos, rClipPoly, rTransform );
407 //////////////////////////////////////////////////////////////////////////////////
408 // DXSurfaceBitmap::draw
409 //////////////////////////////////////////////////////////////////////////////////
411 bool DXSurfaceBitmap::draw( double fAlpha,
412 const ::basegfx::B2DPoint& rPos,
413 const ::basegfx::B2DRange& rArea,
414 const ::basegfx::B2DHomMatrix& rTransform )
416 if( mbIsSurfaceDirty )
418 mpSurfaceProxy->setColorBufferDirty();
419 mbIsSurfaceDirty = false;
422 return mpSurfaceProxy->draw( fAlpha, rPos, rArea, rTransform );
425 //////////////////////////////////////////////////////////////////////////////////
426 // DXSurfaceBitmap::draw
427 //////////////////////////////////////////////////////////////////////////////////
429 bool DXSurfaceBitmap::draw( double fAlpha,
430 const ::basegfx::B2DPoint& rPos,
431 const ::basegfx::B2DHomMatrix& rTransform )
433 if( mbIsSurfaceDirty )
435 mpSurfaceProxy->setColorBufferDirty();
436 mbIsSurfaceDirty = false;
439 return mpSurfaceProxy->draw( fAlpha, rPos, rTransform );
442 //////////////////////////////////////////////////////////////////////////////////
443 // DXSurfaceBitmap::draw
444 //////////////////////////////////////////////////////////////////////////////////
446 bool DXSurfaceBitmap::draw( const ::basegfx::B2IRange& rArea )
448 if( mbIsSurfaceDirty )
450 mpSurfaceProxy->setColorBufferDirty();
451 mbIsSurfaceDirty = false;
454 const double fAlpha(1.0);
455 const ::basegfx::B2DHomMatrix aTransform;
456 const ::basegfx::B2DRange aIEEEArea( rArea );
457 return mpSurfaceProxy->draw(fAlpha,
458 ::basegfx::B2DPoint(),
459 aIEEEArea,
460 aTransform);
463 //////////////////////////////////////////////////////////////////////////////////
464 // DXSurfaceBitmap::imageDebugger
465 //////////////////////////////////////////////////////////////////////////////////
466 #if defined(DX_DEBUG_IMAGES)
467 # if OSL_DEBUG_LEVEL > 0
468 void DXSurfaceBitmap::imageDebugger()
470 #if DIRECTX_VERSION < 0x0900
471 DDSURFACEDESC aSurfaceDesc;
472 memset( &aSurfaceDesc, 0, sizeof(DDSURFACEDESC) );
473 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
475 if( FAILED(mpSurface->Lock( NULL,
476 &aSurfaceDesc,
477 DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY,
478 NULL)) )
479 return;
481 imdebug("bgra w=%d h=%d %p", aSurfaceDesc.dwWidth, aSurfaceDesc.dwHeight, aSurfaceDesc.lpSurface);
483 mpSurface->Unlock(NULL);
484 #else
485 D3DLOCKED_RECT aLockedRect;
486 if( FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)) )
487 return;
489 imdebug("bgra w=%d h=%d %p", maSize.getX(),
490 maSize.getY(), aLockedRect.pBits);
491 mpSurface->UnlockRect();
492 #endif
494 # endif
495 #endif
497 //////////////////////////////////////////////////////////////////////////////////
498 // DXSurfaceBitmap::getData
499 //////////////////////////////////////////////////////////////////////////////////
501 uno::Sequence< sal_Int8 > DXSurfaceBitmap::getData( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
502 const geometry::IntegerRectangle2D& rect )
504 if(hasAlpha())
506 uno::Sequence< sal_Int8 > aRes( (rect.X2-rect.X1)*(rect.Y2-rect.Y1)*4 ); // TODO(F1): Be format-agnostic here
508 const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
510 Gdiplus::BitmapData aBmpData;
511 aBmpData.Width = rect.X2-rect.X1;
512 aBmpData.Height = rect.Y2-rect.Y1;
513 aBmpData.Stride = 4*aBmpData.Width;
514 aBmpData.PixelFormat = PixelFormat32bppARGB;
515 aBmpData.Scan0 = aRes.getArray();
517 // TODO(F1): Support more pixel formats natively
519 // read data from bitmap
520 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
521 Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf,
522 PixelFormat32bppARGB, // TODO(F1): Adapt to
523 // Graphics native
524 // format/change
525 // getMemoryLayout
526 &aBmpData ) )
528 // failed to lock, bail out
529 return uno::Sequence< sal_Int8 >();
532 mpGDIPlusBitmap->UnlockBits( &aBmpData );
534 return aRes;
536 else
538 sal_uInt32 nWidth = rect.X2-rect.X1;
539 sal_uInt32 nHeight = rect.Y2-rect.Y1;
541 uno::Sequence< sal_Int8 > aRes(nWidth*nHeight*4);
543 #if DIRECTX_VERSION < 0x0900
544 DDSURFACEDESC aSurfaceDesc;
545 memset(&aSurfaceDesc,0, sizeof(DDSURFACEDESC));
546 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
547 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
549 // lock the directx surface to receive the pointer to the surface memory.
550 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
551 return uno::Sequence< sal_Int8 >();
553 sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1);
554 sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray();
555 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
556 for(sal_uInt32 y=0; y<nHeight; ++y)
558 memcpy(pDst,pSrc,nSegmentSizeInBytes);
559 pDst += nSegmentSizeInBytes;
560 pSrc += aSurfaceDesc.lPitch;
563 mpSurface->Unlock(NULL);
564 #else
565 D3DLOCKED_RECT aLockedRect;
566 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
567 return uno::Sequence< sal_Int8 >();
569 sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1);
570 sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray();
571 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
572 for(sal_uInt32 y=0; y<nHeight; ++y)
574 memcpy(pDst,pSrc,nSegmentSizeInBytes);
575 pDst += nSegmentSizeInBytes;
576 pSrc += aLockedRect.Pitch;
579 mpSurface->UnlockRect();
580 #endif
581 return aRes;
585 //////////////////////////////////////////////////////////////////////////////////
586 // DXSurfaceBitmap::setData
587 //////////////////////////////////////////////////////////////////////////////////
589 void DXSurfaceBitmap::setData( const uno::Sequence< sal_Int8 >& data,
590 const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
591 const geometry::IntegerRectangle2D& rect )
593 if(hasAlpha())
595 const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
597 Gdiplus::BitmapData aBmpData;
598 aBmpData.Width = rect.X2-rect.X1;
599 aBmpData.Height = rect.Y2-rect.Y1;
600 aBmpData.Stride = 4*aBmpData.Width;
601 aBmpData.PixelFormat = PixelFormat32bppARGB;
602 aBmpData.Scan0 = (void*)data.getConstArray();
604 // TODO(F1): Support more pixel formats natively
606 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect,
607 Gdiplus::ImageLockModeWrite | Gdiplus::ImageLockModeUserInputBuf,
608 PixelFormat32bppARGB, // TODO: Adapt to
609 // Graphics native
610 // format/change
611 // getMemoryLayout
612 &aBmpData ) )
614 throw uno::RuntimeException();
617 // commit data to bitmap
618 mpGDIPlusBitmap->UnlockBits( &aBmpData );
620 else
622 sal_uInt32 nWidth = rect.X2-rect.X1;
623 sal_uInt32 nHeight = rect.Y2-rect.Y1;
625 #if DIRECTX_VERSION < 0x0900
626 DDSURFACEDESC aSurfaceDesc;
627 memset(&aSurfaceDesc, 0, sizeof(DDSURFACEDESC));
628 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
629 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY;
631 // lock the directx surface to receive the pointer to the surface memory.
632 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
633 throw uno::RuntimeException();
635 sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray();
636 sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1);
637 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
638 for(sal_uInt32 y=0; y<nHeight; ++y)
640 memcpy(pDst,pSrc,nSegmentSizeInBytes);
641 pSrc += nSegmentSizeInBytes;
642 pDst += aSurfaceDesc.lPitch;
645 mpSurface->Unlock(NULL);
646 #else
647 // lock the directx surface to receive the pointer to the surface memory.
648 D3DLOCKED_RECT aLockedRect;
649 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
650 throw uno::RuntimeException();
652 sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray();
653 sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1);
654 sal_uInt32 nSegmentSizeInBytes = nWidth<<4;
655 for(sal_uInt32 y=0; y<nHeight; ++y)
657 memcpy(pDst,pSrc,nSegmentSizeInBytes);
658 pSrc += nSegmentSizeInBytes;
659 pDst += aLockedRect.Pitch;
662 mpSurface->UnlockRect();
663 #endif
666 mbIsSurfaceDirty = true;
669 //////////////////////////////////////////////////////////////////////////////////
670 // DXSurfaceBitmap::setPixel
671 //////////////////////////////////////////////////////////////////////////////////
673 void DXSurfaceBitmap::setPixel( const uno::Sequence< sal_Int8 >& color,
674 const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
675 const geometry::IntegerPoint2D& pos )
677 if(hasAlpha())
679 const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
681 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
682 "CanvasHelper::setPixel: X coordinate out of bounds" );
683 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
684 "CanvasHelper::setPixel: Y coordinate out of bounds" );
685 ENSURE_ARG_OR_THROW( color.getLength() > 3,
686 "CanvasHelper::setPixel: not enough color components" );
688 if( Gdiplus::Ok != mpGDIPlusBitmap->SetPixel( pos.X, pos.Y,
689 Gdiplus::Color( tools::sequenceToArgb( color ))))
691 throw uno::RuntimeException();
694 else
696 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(),
697 "CanvasHelper::setPixel: X coordinate out of bounds" );
698 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(),
699 "CanvasHelper::setPixel: Y coordinate out of bounds" );
700 ENSURE_ARG_OR_THROW( color.getLength() > 3,
701 "CanvasHelper::setPixel: not enough color components" );
703 Gdiplus::Color aColor(tools::sequenceToArgb(color));
705 #if DIRECTX_VERSION < 0x0900
706 DDSURFACEDESC aSurfaceDesc;
707 memset(&aSurfaceDesc, 0, sizeof(DDSURFACEDESC));
708 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
709 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY;
711 // lock the directx surface to receive the pointer to the surface memory.
712 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
713 throw uno::RuntimeException();
715 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X);
716 *pDst = aColor.GetValue();
717 mpSurface->Unlock(NULL);
718 #else
719 // lock the directx surface to receive the pointer to the surface memory.
720 D3DLOCKED_RECT aLockedRect;
721 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
722 throw uno::RuntimeException();
724 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X);
725 *pDst = aColor.GetValue();
726 mpSurface->UnlockRect();
727 #endif
730 mbIsSurfaceDirty = true;
733 //////////////////////////////////////////////////////////////////////////////////
734 // DXSurfaceBitmap::getPixel
735 //////////////////////////////////////////////////////////////////////////////////
737 uno::Sequence< sal_Int8 > DXSurfaceBitmap::getPixel( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
738 const geometry::IntegerPoint2D& pos )
740 if(hasAlpha())
742 const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
744 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
745 "CanvasHelper::getPixel: X coordinate out of bounds" );
746 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
747 "CanvasHelper::getPixel: Y coordinate out of bounds" );
749 Gdiplus::Color aColor;
751 if( Gdiplus::Ok != mpGDIPlusBitmap->GetPixel( pos.X, pos.Y, &aColor ) )
752 return uno::Sequence< sal_Int8 >();
754 return tools::argbToIntSequence(aColor.GetValue());
756 else
758 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(),
759 "CanvasHelper::getPixel: X coordinate out of bounds" );
760 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(),
761 "CanvasHelper::getPixel: Y coordinate out of bounds" );
763 #if DIRECTX_VERSION < 0x0900
764 DDSURFACEDESC aSurfaceDesc;
765 memset(&aSurfaceDesc, 0, sizeof(DDSURFACEDESC));
766 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
767 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY;
769 // lock the directx surface to receive the pointer to the surface memory.
770 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL)))
771 throw uno::RuntimeException();
773 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X);
774 Gdiplus::Color aColor(*pDst);
775 mpSurface->Unlock(NULL);
776 #else
777 // lock the directx surface to receive the pointer to the surface memory.
778 D3DLOCKED_RECT aLockedRect;
779 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)))
780 throw uno::RuntimeException();
782 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X);
783 Gdiplus::Color aColor(*pDst);
784 mpSurface->UnlockRect();
785 #endif
787 return tools::argbToIntSequence(aColor.GetValue());
792 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */