1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
41 using namespace ::com::sun::star
;
47 //////////////////////////////////////////////////////////////////////////////////
49 //////////////////////////////////////////////////////////////////////////////////
51 struct DXColorBuffer
: public canvas::IColorBuffer
54 DXColorBuffer( const COMReference
<surface_type
>& rSurface
,
55 const ::basegfx::B2IVector
& rSize
) :
62 // implementation of the 'IColorBuffer' interface
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;
74 ::basegfx::B2IVector maSize
;
75 #if DIRECTX_VERSION < 0x0900
76 mutable DDSURFACEDESC aSurfaceDesc
;
78 mutable D3DLOCKED_RECT maLockedRect
;
80 mutable COMReference
<surface_type
> mpSurface
;
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
);
93 if(SUCCEEDED(mpSurface
->LockRect(&maLockedRect
,NULL
,D3DLOCK_NOSYSLOCK
|D3DLOCK_READONLY
)))
94 return static_cast<sal_uInt8
*>(maLockedRect
.pBits
);
99 void DXColorBuffer::unlock() const
101 #if DIRECTX_VERSION < 0x0900
102 mpSurface
->Unlock(NULL
);
104 mpSurface
->UnlockRect();
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
;
123 return maLockedRect
.Pitch
;
127 canvas::IColorBuffer::Format
DXColorBuffer::getFormat() const
129 return canvas::IColorBuffer::FMT_X8R8G8B8
;
132 //////////////////////////////////////////////////////////////////////////////////
134 //////////////////////////////////////////////////////////////////////////////////
136 struct GDIColorBuffer
: public canvas::IColorBuffer
140 GDIColorBuffer( const BitmapSharedPtr
& rSurface
,
141 const ::basegfx::B2IVector
& rSize
) :
142 mpGDIPlusBitmap(rSurface
),
148 // implementation of the 'IColorBuffer' interface
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;
160 ::basegfx::B2IVector maSize
;
161 mutable Gdiplus::BitmapData aBmpData
;
162 BitmapSharedPtr mpGDIPlusBitmap
;
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
,
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
,
219 mpGdiPlusUser( GDIPlusUser::createInstance() ),
221 mpRenderModule(rRenderModule
),
222 mpSurfaceManager(rMgr
),
228 mbIsSurfaceDirty(true),
234 //////////////////////////////////////////////////////////////////////////////////
235 // DXSurfaceBitmap::getSize
236 //////////////////////////////////////////////////////////////////////////////////
238 ::basegfx::B2IVector
DXSurfaceBitmap::getSize() const
243 //////////////////////////////////////////////////////////////////////////////////
244 // DXSurfaceBitmap::init
245 //////////////////////////////////////////////////////////////////////////////////
247 void DXSurfaceBitmap::init()
249 // create container for pixel data
252 mpGDIPlusBitmap
.reset(
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
));
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
)
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
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
327 mbIsSurfaceDirty
= true;
332 return createSurfaceGraphics(mpSurface
);
335 //////////////////////////////////////////////////////////////////////////////////
336 // DXSurfaceBitmap::getBitmap
337 //////////////////////////////////////////////////////////////////////////////////
339 BitmapSharedPtr
DXSurfaceBitmap::getBitmap() const
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(),
363 (BYTE
*)aSurfaceDesc
.lpSurface
));
365 // unlock the directx surface
366 mpSurface
->Unlock(NULL
);
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(),
380 (BYTE
*)aLockedRect
.pBits
));
382 mpSurface
->UnlockRect();
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(),
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
,
477 DDLOCK_NOSYSLOCK
|DDLOCK_SURFACEMEMORYPTR
|DDLOCK_WAIT
|DDLOCK_READONLY
,
481 imdebug("bgra w=%d h=%d %p", aSurfaceDesc
.dwWidth
, aSurfaceDesc
.dwHeight
, aSurfaceDesc
.lpSurface
);
483 mpSurface
->Unlock(NULL
);
485 D3DLOCKED_RECT aLockedRect
;
486 if( FAILED(mpSurface
->LockRect(&aLockedRect
,NULL
,D3DLOCK_NOSYSLOCK
|D3DLOCK_READONLY
)) )
489 imdebug("bgra w=%d h=%d %p", maSize
.getX(),
490 maSize
.getY(), aLockedRect
.pBits
);
491 mpSurface
->UnlockRect();
497 //////////////////////////////////////////////////////////////////////////////////
498 // DXSurfaceBitmap::getData
499 //////////////////////////////////////////////////////////////////////////////////
501 uno::Sequence
< sal_Int8
> DXSurfaceBitmap::getData( rendering::IntegerBitmapLayout
& /*bitmapLayout*/,
502 const geometry::IntegerRectangle2D
& rect
)
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
528 // failed to lock, bail out
529 return uno::Sequence
< sal_Int8
>();
532 mpGDIPlusBitmap
->UnlockBits( &aBmpData
);
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
);
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();
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
)
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
614 throw uno::RuntimeException();
617 // commit data to bitmap
618 mpGDIPlusBitmap
->UnlockBits( &aBmpData
);
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
);
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();
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
)
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();
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
);
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();
730 mbIsSurfaceDirty
= true;
733 //////////////////////////////////////////////////////////////////////////////////
734 // DXSurfaceBitmap::getPixel
735 //////////////////////////////////////////////////////////////////////////////////
737 uno::Sequence
< sal_Int8
> DXSurfaceBitmap::getPixel( rendering::IntegerBitmapLayout
& /*bitmapLayout*/,
738 const geometry::IntegerPoint2D
& pos
)
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());
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
);
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();
787 return tools::argbToIntSequence(aColor
.GetValue());
792 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */