| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_canvas.hxx" |
| |
| #include "dx_surfacebitmap.hxx" |
| #include "dx_impltools.hxx" |
| #include "dx_surfacegraphics.hxx" |
| #include "dx_graphicsprovider.hxx" |
| |
| #include <canvas/debug.hxx> |
| #include <tools/diagnose_ex.h> |
| |
| #include <basegfx/matrix/b2dhommatrix.hxx> |
| #include <basegfx/range/b2irange.hxx> |
| |
| #if defined(DX_DEBUG_IMAGES) |
| # if OSL_DEBUG_LEVEL > 0 |
| # include <imdebug.h> |
| # undef min |
| # undef max |
| # endif |
| #endif |
| |
| using namespace ::com::sun::star; |
| |
| namespace dxcanvas |
| { |
| namespace |
| { |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXColorBuffer |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| struct DXColorBuffer : public canvas::IColorBuffer |
| { |
| public: |
| DXColorBuffer( const COMReference<surface_type>& rSurface, |
| const ::basegfx::B2IVector& rSize ) : |
| mpSurface(rSurface), |
| maSize(rSize), |
| mbAlpha(false) |
| { |
| } |
| |
| // implementation of the 'IColorBuffer' interface |
| public: |
| |
| virtual sal_uInt8* lock() const; |
| virtual void unlock() const; |
| virtual sal_uInt32 getWidth() const; |
| virtual sal_uInt32 getHeight() const; |
| virtual sal_uInt32 getStride() const; |
| virtual Format getFormat() const; |
| |
| private: |
| |
| ::basegfx::B2IVector maSize; |
| #if DIRECTX_VERSION < 0x0900 |
| mutable DDSURFACEDESC aSurfaceDesc; |
| #else |
| mutable D3DLOCKED_RECT maLockedRect; |
| #endif |
| mutable COMReference<surface_type> mpSurface; |
| bool mbAlpha; |
| }; |
| |
| sal_uInt8* DXColorBuffer::lock() const |
| { |
| #if DIRECTX_VERSION < 0x0900 |
| rtl_fillMemory((void *)&aSurfaceDesc,sizeof(DDSURFACEDESC),0); |
| aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); |
| const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY; |
| if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) |
| return static_cast<sal_uInt8 *>(aSurfaceDesc.lpSurface); |
| #else |
| if(SUCCEEDED(mpSurface->LockRect(&maLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) |
| return static_cast<sal_uInt8 *>(maLockedRect.pBits); |
| #endif |
| return NULL; |
| } |
| |
| void DXColorBuffer::unlock() const |
| { |
| #if DIRECTX_VERSION < 0x0900 |
| mpSurface->Unlock(NULL); |
| #else |
| mpSurface->UnlockRect(); |
| #endif |
| } |
| |
| sal_uInt32 DXColorBuffer::getWidth() const |
| { |
| return maSize.getX(); |
| } |
| |
| sal_uInt32 DXColorBuffer::getHeight() const |
| { |
| return maSize.getY(); |
| } |
| |
| sal_uInt32 DXColorBuffer::getStride() const |
| { |
| #if DIRECTX_VERSION < 0x0900 |
| return aSurfaceDesc.lPitch; |
| #else |
| return maLockedRect.Pitch; |
| #endif |
| } |
| |
| canvas::IColorBuffer::Format DXColorBuffer::getFormat() const |
| { |
| return canvas::IColorBuffer::FMT_X8R8G8B8; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // GDIColorBuffer |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| struct GDIColorBuffer : public canvas::IColorBuffer |
| { |
| public: |
| |
| GDIColorBuffer( const BitmapSharedPtr& rSurface, |
| const ::basegfx::B2IVector& rSize ) : |
| mpGDIPlusBitmap(rSurface), |
| maSize(rSize), |
| mbAlpha(true) |
| { |
| } |
| |
| // implementation of the 'IColorBuffer' interface |
| public: |
| |
| virtual sal_uInt8* lock() const; |
| virtual void unlock() const; |
| virtual sal_uInt32 getWidth() const; |
| virtual sal_uInt32 getHeight() const; |
| virtual sal_uInt32 getStride() const; |
| virtual Format getFormat() const; |
| |
| private: |
| |
| ::basegfx::B2IVector maSize; |
| mutable Gdiplus::BitmapData aBmpData; |
| BitmapSharedPtr mpGDIPlusBitmap; |
| bool mbAlpha; |
| }; |
| |
| sal_uInt8* GDIColorBuffer::lock() const |
| { |
| aBmpData.Width = maSize.getX(); |
| aBmpData.Height = maSize.getY(); |
| aBmpData.Stride = 4*aBmpData.Width; |
| aBmpData.PixelFormat = PixelFormat32bppARGB; |
| aBmpData.Scan0 = NULL; |
| const Gdiplus::Rect aRect( 0,0,aBmpData.Width,aBmpData.Height ); |
| if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect, |
| Gdiplus::ImageLockModeRead, |
| PixelFormat32bppARGB, |
| &aBmpData ) ) |
| { |
| return NULL; |
| } |
| |
| return static_cast<sal_uInt8*>(aBmpData.Scan0); |
| } |
| |
| void GDIColorBuffer::unlock() const |
| { |
| mpGDIPlusBitmap->UnlockBits( &aBmpData ); |
| } |
| |
| sal_uInt32 GDIColorBuffer::getWidth() const |
| { |
| return maSize.getX(); |
| } |
| |
| sal_uInt32 GDIColorBuffer::getHeight() const |
| { |
| return maSize.getY(); |
| } |
| |
| sal_uInt32 GDIColorBuffer::getStride() const |
| { |
| return aBmpData.Stride; |
| } |
| |
| canvas::IColorBuffer::Format GDIColorBuffer::getFormat() const |
| { |
| return canvas::IColorBuffer::FMT_A8R8G8B8; |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::DXSurfaceBitmap |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| DXSurfaceBitmap::DXSurfaceBitmap( const ::basegfx::B2IVector& rSize, |
| const canvas::ISurfaceProxyManagerSharedPtr& rMgr, |
| const IDXRenderModuleSharedPtr& rRenderModule, |
| bool bWithAlpha ) : |
| mpGdiPlusUser( GDIPlusUser::createInstance() ), |
| maSize(rSize), |
| mpRenderModule(rRenderModule), |
| mpSurfaceManager(rMgr), |
| mpSurfaceProxy(), |
| mpSurface(), |
| mpGDIPlusBitmap(), |
| mpGraphics(), |
| mpColorBuffer(), |
| mbIsSurfaceDirty(true), |
| mbAlpha(bWithAlpha) |
| { |
| init(); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::getSize |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| ::basegfx::B2IVector DXSurfaceBitmap::getSize() const |
| { |
| return maSize; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::init |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| void DXSurfaceBitmap::init() |
| { |
| // create container for pixel data |
| if(mbAlpha) |
| { |
| mpGDIPlusBitmap.reset( |
| new Gdiplus::Bitmap( |
| maSize.getX(), |
| maSize.getY(), |
| PixelFormat32bppARGB |
| )); |
| mpGraphics.reset( tools::createGraphicsFromBitmap(mpGDIPlusBitmap) ); |
| |
| // create the colorbuffer object, which is basically a simple |
| // wrapper around the directx surface. the colorbuffer is the |
| // interface which is used by the surfaceproxy to support any |
| // kind of underlying structure for the pixel data container. |
| mpColorBuffer.reset(new GDIColorBuffer(mpGDIPlusBitmap,maSize)); |
| } |
| else |
| { |
| mpSurface = mpRenderModule->createSystemMemorySurface(maSize); |
| |
| // create the colorbuffer object, which is basically a simple |
| // wrapper around the directx surface. the colorbuffer is the |
| // interface which is used by the surfaceproxy to support any |
| // kind of underlying structure for the pixel data container. |
| mpColorBuffer.reset(new DXColorBuffer(mpSurface,maSize)); |
| } |
| |
| // create a (possibly hardware accelerated) mirror surface. |
| mpSurfaceProxy = mpSurfaceManager->createSurfaceProxy(mpColorBuffer); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::resize |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| bool DXSurfaceBitmap::resize( const ::basegfx::B2IVector& rSize ) |
| { |
| if(maSize != rSize) |
| { |
| maSize = rSize; |
| init(); |
| } |
| |
| return true; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::clear |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| void DXSurfaceBitmap::clear() |
| { |
| GraphicsSharedPtr pGraphics(getGraphics()); |
| Gdiplus::Color transColor(255,0,0,0); |
| pGraphics->SetCompositingMode( Gdiplus::CompositingModeSourceCopy ); |
| pGraphics->Clear( transColor ); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::hasAlpha |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| bool DXSurfaceBitmap::hasAlpha() const |
| { |
| return mbAlpha; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::getGraphics |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| GraphicsSharedPtr DXSurfaceBitmap::getGraphics() |
| { |
| // since clients will most probably draw directly |
| // to the GDI+ bitmap, we need to mark it as dirty |
| // to ensure that the corrosponding dxsurface will |
| // be updated. |
| mbIsSurfaceDirty = true; |
| |
| if(hasAlpha()) |
| return mpGraphics; |
| else |
| return createSurfaceGraphics(mpSurface); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::getBitmap |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| BitmapSharedPtr DXSurfaceBitmap::getBitmap() const |
| { |
| if(hasAlpha()) |
| return mpGDIPlusBitmap; |
| |
| BitmapSharedPtr pResult; |
| |
| #if DIRECTX_VERSION < 0x0900 |
| DDSURFACEDESC aSurfaceDesc; |
| rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); |
| aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); |
| const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY; |
| |
| // lock the directx surface to receive the pointer to the surface memory. |
| if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) |
| { |
| // decide about the format we pass the gdi+, the directx surface is always |
| // 32bit, either with or without alpha component. |
| Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB; |
| |
| // construct a gdi+ bitmap from the raw pixel data. |
| pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(), |
| aSurfaceDesc.lPitch, |
| nFormat, |
| (BYTE *)aSurfaceDesc.lpSurface )); |
| |
| // unlock the directx surface |
| mpSurface->Unlock(NULL); |
| } |
| #else |
| D3DLOCKED_RECT aLockedRect; |
| if(SUCCEEDED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) |
| { |
| // decide about the format we pass the gdi+, the directx surface is always |
| // 32bit, either with or without alpha component. |
| Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB; |
| |
| // construct a gdi+ bitmap from the raw pixel data. |
| pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(), |
| aLockedRect.Pitch, |
| nFormat, |
| (BYTE *)aLockedRect.pBits )); |
| |
| mpSurface->UnlockRect(); |
| } |
| #endif |
| |
| return pResult; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::draw |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| bool DXSurfaceBitmap::draw( double fAlpha, |
| const ::basegfx::B2DPoint& rPos, |
| const ::basegfx::B2DPolyPolygon& rClipPoly, |
| const ::basegfx::B2DHomMatrix& rTransform ) |
| { |
| if( mbIsSurfaceDirty ) |
| { |
| mpSurfaceProxy->setColorBufferDirty(); |
| mbIsSurfaceDirty = false; |
| } |
| |
| return mpSurfaceProxy->draw( fAlpha, rPos, rClipPoly, rTransform ); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::draw |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| bool DXSurfaceBitmap::draw( double fAlpha, |
| const ::basegfx::B2DPoint& rPos, |
| const ::basegfx::B2DRange& rArea, |
| const ::basegfx::B2DHomMatrix& rTransform ) |
| { |
| if( mbIsSurfaceDirty ) |
| { |
| mpSurfaceProxy->setColorBufferDirty(); |
| mbIsSurfaceDirty = false; |
| } |
| |
| return mpSurfaceProxy->draw( fAlpha, rPos, rArea, rTransform ); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::draw |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| bool DXSurfaceBitmap::draw( double fAlpha, |
| const ::basegfx::B2DPoint& rPos, |
| const ::basegfx::B2DHomMatrix& rTransform ) |
| { |
| if( mbIsSurfaceDirty ) |
| { |
| mpSurfaceProxy->setColorBufferDirty(); |
| mbIsSurfaceDirty = false; |
| } |
| |
| return mpSurfaceProxy->draw( fAlpha, rPos, rTransform ); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::draw |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| bool DXSurfaceBitmap::draw( const ::basegfx::B2IRange& rArea ) |
| { |
| if( mbIsSurfaceDirty ) |
| { |
| mpSurfaceProxy->setColorBufferDirty(); |
| mbIsSurfaceDirty = false; |
| } |
| |
| const double fAlpha(1.0); |
| const ::basegfx::B2DHomMatrix aTransform; |
| const ::basegfx::B2DRange aIEEEArea( rArea ); |
| return mpSurfaceProxy->draw(fAlpha, |
| ::basegfx::B2DPoint(), |
| aIEEEArea, |
| aTransform); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::imageDebugger |
| ////////////////////////////////////////////////////////////////////////////////// |
| #if defined(DX_DEBUG_IMAGES) |
| # if OSL_DEBUG_LEVEL > 0 |
| void DXSurfaceBitmap::imageDebugger() |
| { |
| #if DIRECTX_VERSION < 0x0900 |
| DDSURFACEDESC aSurfaceDesc; |
| rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 ); |
| aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); |
| |
| if( FAILED(mpSurface->Lock( NULL, |
| &aSurfaceDesc, |
| DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY, |
| NULL)) ) |
| return; |
| |
| imdebug("bgra w=%d h=%d %p", aSurfaceDesc.dwWidth, aSurfaceDesc.dwHeight, aSurfaceDesc.lpSurface); |
| |
| mpSurface->Unlock(NULL); |
| #else |
| D3DLOCKED_RECT aLockedRect; |
| if( FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)) ) |
| return; |
| |
| imdebug("bgra w=%d h=%d %p", maSize.getX(), |
| maSize.getY(), aLockedRect.pBits); |
| mpSurface->UnlockRect(); |
| #endif |
| } |
| # endif |
| #endif |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::getData |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| uno::Sequence< sal_Int8 > DXSurfaceBitmap::getData( rendering::IntegerBitmapLayout& /*bitmapLayout*/, |
| const geometry::IntegerRectangle2D& rect ) |
| { |
| if(hasAlpha()) |
| { |
| uno::Sequence< sal_Int8 > aRes( (rect.X2-rect.X1)*(rect.Y2-rect.Y1)*4 ); // TODO(F1): Be format-agnostic here |
| |
| const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) ); |
| |
| Gdiplus::BitmapData aBmpData; |
| aBmpData.Width = rect.X2-rect.X1; |
| aBmpData.Height = rect.Y2-rect.Y1; |
| aBmpData.Stride = 4*aBmpData.Width; |
| aBmpData.PixelFormat = PixelFormat32bppARGB; |
| aBmpData.Scan0 = aRes.getArray(); |
| |
| // TODO(F1): Support more pixel formats natively |
| |
| // read data from bitmap |
| if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect, |
| Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf, |
| PixelFormat32bppARGB, // TODO(F1): Adapt to |
| // Graphics native |
| // format/change |
| // getMemoryLayout |
| &aBmpData ) ) |
| { |
| // failed to lock, bail out |
| return uno::Sequence< sal_Int8 >(); |
| } |
| |
| mpGDIPlusBitmap->UnlockBits( &aBmpData ); |
| |
| return aRes; |
| } |
| else |
| { |
| sal_uInt32 nWidth = rect.X2-rect.X1; |
| sal_uInt32 nHeight = rect.Y2-rect.Y1; |
| |
| uno::Sequence< sal_Int8 > aRes(nWidth*nHeight*4); |
| |
| #if DIRECTX_VERSION < 0x0900 |
| DDSURFACEDESC aSurfaceDesc; |
| rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); |
| aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); |
| const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY; |
| |
| // lock the directx surface to receive the pointer to the surface memory. |
| if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) |
| return uno::Sequence< sal_Int8 >(); |
| |
| sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1); |
| sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray(); |
| sal_uInt32 nSegmentSizeInBytes = nWidth<<4; |
| for(sal_uInt32 y=0; y<nHeight; ++y) |
| { |
| rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes); |
| pDst += nSegmentSizeInBytes; |
| pSrc += aSurfaceDesc.lPitch; |
| } |
| |
| mpSurface->Unlock(NULL); |
| #else |
| D3DLOCKED_RECT aLockedRect; |
| if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) |
| return uno::Sequence< sal_Int8 >(); |
| |
| sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1); |
| sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray(); |
| sal_uInt32 nSegmentSizeInBytes = nWidth<<4; |
| for(sal_uInt32 y=0; y<nHeight; ++y) |
| { |
| rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes); |
| pDst += nSegmentSizeInBytes; |
| pSrc += aLockedRect.Pitch; |
| } |
| |
| mpSurface->UnlockRect(); |
| #endif |
| return aRes; |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::setData |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| void DXSurfaceBitmap::setData( const uno::Sequence< sal_Int8 >& data, |
| const rendering::IntegerBitmapLayout& /*bitmapLayout*/, |
| const geometry::IntegerRectangle2D& rect ) |
| { |
| if(hasAlpha()) |
| { |
| const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) ); |
| |
| Gdiplus::BitmapData aBmpData; |
| aBmpData.Width = rect.X2-rect.X1; |
| aBmpData.Height = rect.Y2-rect.Y1; |
| aBmpData.Stride = 4*aBmpData.Width; |
| aBmpData.PixelFormat = PixelFormat32bppARGB; |
| aBmpData.Scan0 = (void*)data.getConstArray(); |
| |
| // TODO(F1): Support more pixel formats natively |
| |
| if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect, |
| Gdiplus::ImageLockModeWrite | Gdiplus::ImageLockModeUserInputBuf, |
| PixelFormat32bppARGB, // TODO: Adapt to |
| // Graphics native |
| // format/change |
| // getMemoryLayout |
| &aBmpData ) ) |
| { |
| throw uno::RuntimeException(); |
| } |
| |
| // commit data to bitmap |
| mpGDIPlusBitmap->UnlockBits( &aBmpData ); |
| } |
| else |
| { |
| sal_uInt32 nWidth = rect.X2-rect.X1; |
| sal_uInt32 nHeight = rect.Y2-rect.Y1; |
| |
| #if DIRECTX_VERSION < 0x0900 |
| DDSURFACEDESC aSurfaceDesc; |
| rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); |
| aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); |
| const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY; |
| |
| // lock the directx surface to receive the pointer to the surface memory. |
| if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) |
| throw uno::RuntimeException(); |
| |
| sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray(); |
| sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1); |
| sal_uInt32 nSegmentSizeInBytes = nWidth<<4; |
| for(sal_uInt32 y=0; y<nHeight; ++y) |
| { |
| rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes); |
| pSrc += nSegmentSizeInBytes; |
| pDst += aSurfaceDesc.lPitch; |
| } |
| |
| mpSurface->Unlock(NULL); |
| #else |
| // lock the directx surface to receive the pointer to the surface memory. |
| D3DLOCKED_RECT aLockedRect; |
| if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) |
| throw uno::RuntimeException(); |
| |
| sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray(); |
| sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1); |
| sal_uInt32 nSegmentSizeInBytes = nWidth<<4; |
| for(sal_uInt32 y=0; y<nHeight; ++y) |
| { |
| rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes); |
| pSrc += nSegmentSizeInBytes; |
| pDst += aLockedRect.Pitch; |
| } |
| |
| mpSurface->UnlockRect(); |
| #endif |
| } |
| |
| mbIsSurfaceDirty = true; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::setPixel |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| void DXSurfaceBitmap::setPixel( const uno::Sequence< sal_Int8 >& color, |
| const rendering::IntegerBitmapLayout& /*bitmapLayout*/, |
| const geometry::IntegerPoint2D& pos ) |
| { |
| if(hasAlpha()) |
| { |
| const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() ); |
| |
| ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width, |
| "CanvasHelper::setPixel: X coordinate out of bounds" ); |
| ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height, |
| "CanvasHelper::setPixel: Y coordinate out of bounds" ); |
| ENSURE_ARG_OR_THROW( color.getLength() > 3, |
| "CanvasHelper::setPixel: not enough color components" ); |
| |
| if( Gdiplus::Ok != mpGDIPlusBitmap->SetPixel( pos.X, pos.Y, |
| Gdiplus::Color( tools::sequenceToArgb( color )))) |
| { |
| throw uno::RuntimeException(); |
| } |
| } |
| else |
| { |
| ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(), |
| "CanvasHelper::setPixel: X coordinate out of bounds" ); |
| ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(), |
| "CanvasHelper::setPixel: Y coordinate out of bounds" ); |
| ENSURE_ARG_OR_THROW( color.getLength() > 3, |
| "CanvasHelper::setPixel: not enough color components" ); |
| |
| Gdiplus::Color aColor(tools::sequenceToArgb(color)); |
| |
| #if DIRECTX_VERSION < 0x0900 |
| DDSURFACEDESC aSurfaceDesc; |
| rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); |
| aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); |
| const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY; |
| |
| // lock the directx surface to receive the pointer to the surface memory. |
| if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) |
| throw uno::RuntimeException(); |
| |
| sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X); |
| *pDst = aColor.GetValue(); |
| mpSurface->Unlock(NULL); |
| #else |
| // lock the directx surface to receive the pointer to the surface memory. |
| D3DLOCKED_RECT aLockedRect; |
| if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) |
| throw uno::RuntimeException(); |
| |
| sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X); |
| *pDst = aColor.GetValue(); |
| mpSurface->UnlockRect(); |
| #endif |
| } |
| |
| mbIsSurfaceDirty = true; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // DXSurfaceBitmap::getPixel |
| ////////////////////////////////////////////////////////////////////////////////// |
| |
| uno::Sequence< sal_Int8 > DXSurfaceBitmap::getPixel( rendering::IntegerBitmapLayout& /*bitmapLayout*/, |
| const geometry::IntegerPoint2D& pos ) |
| { |
| if(hasAlpha()) |
| { |
| const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() ); |
| |
| ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width, |
| "CanvasHelper::getPixel: X coordinate out of bounds" ); |
| ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height, |
| "CanvasHelper::getPixel: Y coordinate out of bounds" ); |
| |
| Gdiplus::Color aColor; |
| |
| if( Gdiplus::Ok != mpGDIPlusBitmap->GetPixel( pos.X, pos.Y, &aColor ) ) |
| return uno::Sequence< sal_Int8 >(); |
| |
| return tools::argbToIntSequence(aColor.GetValue()); |
| } |
| else |
| { |
| ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(), |
| "CanvasHelper::getPixel: X coordinate out of bounds" ); |
| ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(), |
| "CanvasHelper::getPixel: Y coordinate out of bounds" ); |
| |
| #if DIRECTX_VERSION < 0x0900 |
| DDSURFACEDESC aSurfaceDesc; |
| rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); |
| aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); |
| const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY; |
| |
| // lock the directx surface to receive the pointer to the surface memory. |
| if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) |
| throw uno::RuntimeException(); |
| |
| sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X); |
| Gdiplus::Color aColor(*pDst); |
| mpSurface->Unlock(NULL); |
| #else |
| // lock the directx surface to receive the pointer to the surface memory. |
| D3DLOCKED_RECT aLockedRect; |
| if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) |
| throw uno::RuntimeException(); |
| |
| sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X); |
| Gdiplus::Color aColor(*pDst); |
| mpSurface->UnlockRect(); |
| #endif |
| |
| return tools::argbToIntSequence(aColor.GetValue()); |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////////// |
| // End of file |
| ////////////////////////////////////////////////////////////////////////////////// |
| } |
| |