INTEGRATION: CWS canvas05 (1.1.2); FILE ADDED
2008/06/03 23:52:24 thb 1.1.2.5: Removed extra level of indirection for getting a graphics for a surface; removed some unused code 2008/06/03 11:11:24 thb 1.1.2.4: Cleaned up image debugging stuff; fixed a few d3d debug warnings; fixed one deadlock rendering a bitmap from the same surface to itself; fixed premature ReleaseDC call in GraphicsProvider::getGraphics() 2008/05/23 22:03:45 thb 1.1.2.3: Moving all remaining new files to LGPL 3 2008/02/08 00:26:39 thb 1.1.2.2: #81092# Finishing cooperative canvas output stuff 2008/01/22 00:25:24 thb 1.1.2.1: #i81092# Making gdiplus and dx canvas more independent
This commit is contained in:
807
canvas/source/directx/dx_surfacebitmap.cxx
Normal file
807
canvas/source/directx/dx_surfacebitmap.cxx
Normal file
@@ -0,0 +1,807 @@
|
|||||||
|
/*************************************************************************
|
||||||
|
*
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* Copyright 2008 by Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
* OpenOffice.org - a multi-platform office productivity suite
|
||||||
|
*
|
||||||
|
* $RCSfile: dx_surfacebitmap.cxx,v $
|
||||||
|
* $Revision: 1.2 $
|
||||||
|
*
|
||||||
|
* This file is part of OpenOffice.org.
|
||||||
|
*
|
||||||
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License version 3
|
||||||
|
* only, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License version 3 for more details
|
||||||
|
* (a copy is included in the LICENSE file that accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* version 3 along with OpenOffice.org. If not, see
|
||||||
|
* <http://www.openoffice.org/license.html>
|
||||||
|
* for a copy of the LGPLv3 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
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user