diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2007-11-01 17:00:10 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2007-11-01 17:00:10 +0000 |
commit | d034efa5dd0ce46482b815fb57b018217c9d37df (patch) | |
tree | 36e39bc8bb68f1b3b955e863c8224c3432375a02 | |
parent | INTEGRATION: CWS dxliberate01 (1.1.2); FILE ADDED (diff) | |
download | core-d034efa5dd0ce46482b815fb57b018217c9d37df.tar.gz core-d034efa5dd0ce46482b815fb57b018217c9d37df.zip |
INTEGRATION: CWS dxliberate01 (1.1.2); FILE ADDED
2007/07/23 12:05:08 thb 1.1.2.1: #i48454# dxcanvas is now part of OOo
-rwxr-xr-x | canvas/source/directx/dx_sprite.hxx | 59 | ||||
-rwxr-xr-x | canvas/source/directx/dx_spritecanvas.hxx | 161 | ||||
-rwxr-xr-x | canvas/source/directx/dx_spritecanvashelper.cxx | 367 | ||||
-rwxr-xr-x | canvas/source/directx/dx_spritecanvashelper.hxx | 165 | ||||
-rwxr-xr-x | canvas/source/directx/dx_spritehelper.cxx | 221 | ||||
-rwxr-xr-x | canvas/source/directx/dx_spritehelper.hxx | 119 | ||||
-rwxr-xr-x | canvas/source/directx/dx_surfacegraphics.cxx | 104 | ||||
-rwxr-xr-x | canvas/source/directx/dx_surfacegraphics.hxx | 80 | ||||
-rwxr-xr-x | canvas/source/directx/dx_textlayout.cxx | 282 | ||||
-rwxr-xr-x | canvas/source/directx/dx_textlayout.hxx | 122 | ||||
-rwxr-xr-x | canvas/source/directx/dx_textlayout_drawhelper.cxx | 313 | ||||
-rwxr-xr-x | canvas/source/directx/dx_textlayout_drawhelper.hxx | 91 | ||||
-rwxr-xr-x | canvas/source/directx/dx_vcltools.cxx | 553 | ||||
-rwxr-xr-x | canvas/source/directx/dx_vcltools.hxx | 80 |
14 files changed, 2717 insertions, 0 deletions
diff --git a/canvas/source/directx/dx_sprite.hxx b/canvas/source/directx/dx_sprite.hxx new file mode 100755 index 000000000000..48c0f2a6a165 --- /dev/null +++ b/canvas/source/directx/dx_sprite.hxx @@ -0,0 +1,59 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_sprite.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:56:39 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_DXCANVAS_SPRITE_HXX +#define INCLUDED_DXCANVAS_SPRITE_HXX + +#include <canvas/base/sprite.hxx> + +namespace dxcanvas +{ + /** Specialization of ::canvas::Sprite interface, to also provide + redraw methods. + */ + class Sprite : public ::canvas::Sprite + { + public: + + /** Redraw sprite using the hardware + + This method will silently fail, if the previous + restoreTextures() call failed. + */ + virtual void redraw() const = 0; + }; +} + +#endif /* INCLUDED_DXCANVAS_SPRITE_HXX */ diff --git a/canvas/source/directx/dx_spritecanvas.hxx b/canvas/source/directx/dx_spritecanvas.hxx new file mode 100755 index 000000000000..0c735bfee0fa --- /dev/null +++ b/canvas/source/directx/dx_spritecanvas.hxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_spritecanvas.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:57:08 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _DXCANVAS_SPRITECANVAS_HXX_ +#define _DXCANVAS_SPRITECANVAS_HXX_ + +#include <rtl/ref.hxx> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XServiceName.hpp> +#include <com/sun/star/awt/XWindowListener.hpp> +#include <com/sun/star/util/XUpdatable.hpp> +#include <com/sun/star/rendering/XSpriteCanvas.hpp> +#include <com/sun/star/rendering/XIntegerBitmap.hpp> +#include <com/sun/star/rendering/XGraphicDevice.hpp> +#include <com/sun/star/rendering/XBufferController.hpp> +#include <com/sun/star/rendering/XColorSpace.hpp> +#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp> + +#include <cppuhelper/compbase10.hxx> +#include <comphelper/uno3.hxx> + +#include <canvas/base/spritecanvasbase.hxx> +#include <canvas/base/basemutexhelper.hxx> +#include <canvas/base/windowgraphicdevicebase.hxx> + +#include "dx_spritecanvashelper.hxx" +#include "dx_impltools.hxx" +#include "dx_devicehelper.hxx" + + +namespace dxcanvas +{ + typedef ::cppu::WeakComponentImplHelper10< ::com::sun::star::rendering::XSpriteCanvas, + ::com::sun::star::rendering::XIntegerBitmap, + ::com::sun::star::rendering::XGraphicDevice, + ::com::sun::star::rendering::XParametricPolyPolygon2DFactory, + ::com::sun::star::rendering::XBufferController, + ::com::sun::star::rendering::XColorSpace, + ::com::sun::star::awt::XWindowListener, + ::com::sun::star::util::XUpdatable, + ::com::sun::star::beans::XPropertySet, + ::com::sun::star::lang::XServiceName > WindowGraphicDeviceBase_Base; + typedef ::canvas::WindowGraphicDeviceBase< ::canvas::BaseMutexHelper< WindowGraphicDeviceBase_Base >, + DeviceHelper, + ::osl::MutexGuard, + ::cppu::OWeakObject > SpriteCanvasBase_Base; + /** Mixin SpriteSurface + + Have to mixin the SpriteSurface before deriving from + ::canvas::SpriteCanvasBase, as this template should already + implement some of those interface methods. + + The reason why this appears kinda convoluted is the fact that + we cannot specify non-IDL types as WeakComponentImplHelperN + template args, and furthermore, don't want to derive + ::canvas::SpriteCanvasBase directly from + ::canvas::SpriteSurface (because derivees of + ::canvas::SpriteCanvasBase have to explicitely forward the + XInterface methods (e.g. via DECLARE_UNO3_AGG_DEFAULTS) + anyway). Basically, ::canvas::CanvasCustomSpriteBase should + remain a base class that provides implementation, not to + enforce any specific interface on its derivees. + */ + class SpriteCanvasBaseSpriteSurface_Base : public SpriteCanvasBase_Base, + public ::canvas::SpriteSurface + { + }; + + typedef ::canvas::SpriteCanvasBase< SpriteCanvasBaseSpriteSurface_Base, + SpriteCanvasHelper, + ::osl::MutexGuard, + ::cppu::OWeakObject > SpriteCanvasBaseT; + + /** Product of this component's factory. + + The SpriteCanvas object combines the actual Window canvas with + the XGraphicDevice interface. This is because there's a + one-to-one relation between them, anyway, since each window + can have exactly one canvas and one associated + XGraphicDevice. And to avoid messing around with circular + references, this is implemented as one single object. + */ + class SpriteCanvas : public SpriteCanvasBaseT + { + public: + SpriteCanvas( const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Any >& aArguments, + const ::com::sun::star::uno::Reference< + ::com::sun::star::uno::XComponentContext >& rxContext ); + + void initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ); + + /// Dispose all internal references + virtual void SAL_CALL disposing(); + + // Forwarding the XComponent implementation to the + // cppu::ImplHelper templated base + // Classname Base doing refcounting Base implementing the XComponent interface + // | | | + // V V V + DECLARE_UNO3_XCOMPONENT_AGG_DEFAULTS( SpriteCanvas, WindowGraphicDeviceBase_Base, ::cppu::WeakComponentImplHelperBase ); + + // XBufferController (partial) + virtual ::sal_Bool SAL_CALL showBuffer( ::sal_Bool bUpdateAll ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL switchBuffer( ::sal_Bool bUpdateAll ) throw (::com::sun::star::uno::RuntimeException); + + // XSpriteCanvas (partial) + virtual sal_Bool SAL_CALL updateScreen( sal_Bool bUpdateAll ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceName + virtual ::rtl::OUString SAL_CALL getServiceName( ) throw (::com::sun::star::uno::RuntimeException); + + /// Retrieve rendermodule object for this Canvas + const IDXRenderModuleSharedPtr& getRenderModule() const; + + /// Get backbuffer for this canvas + const DXBitmapSharedPtr& getBackBuffer() const; + + private: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxComponentContext; + }; + + typedef ::rtl::Reference< SpriteCanvas > SpriteCanvasRef; + typedef ::rtl::Reference< SpriteCanvas > DeviceRef; +} + +#endif diff --git a/canvas/source/directx/dx_spritecanvashelper.cxx b/canvas/source/directx/dx_spritecanvashelper.cxx new file mode 100755 index 000000000000..ec65a0491374 --- /dev/null +++ b/canvas/source/directx/dx_spritecanvashelper.cxx @@ -0,0 +1,367 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_spritecanvashelper.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:57:22 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <canvas/debug.hxx> +#include <canvas/verbosetrace.hxx> +#include <canvas/canvastools.hxx> + +#include <comphelper/scopeguard.hxx> + +#include <basegfx/range/b2drectangle.hxx> +#include <basegfx/tools/canvastools.hxx> + +#include <boost/cast.hpp> + +#include "dx_spritecanvashelper.hxx" +#include "dx_canvascustomsprite.hxx" + +using namespace ::com::sun::star; + +namespace dxcanvas +{ + namespace + { + void repaintBackground( const ::basegfx::B2DRange& rUpdateArea, + const ::basegfx::B2IRange& rOutputArea, + const DXBitmapSharedPtr& rBackBuffer ) + { + // TODO(E1): Use numeric_cast to catch overflow here + ::basegfx::B2IRange aActualArea( 0, 0, + static_cast<sal_Int32>(rOutputArea.getWidth()), + static_cast<sal_Int32>(rOutputArea.getHeight()) ); + aActualArea.intersect( fround( rUpdateArea ) ); + + // repaint the given area of the screen with background content + rBackBuffer->draw(aActualArea); + } + + void spriteRedraw( const ::canvas::Sprite::Reference& rSprite ) + { + // downcast to derived dxcanvas::Sprite interface, which + // provides the actual redraw methods. + ::boost::polymorphic_downcast< Sprite* >( + rSprite.get() )->redraw(); + } + + void spriteRedrawStub( const ::canvas::Sprite::Reference& rSprite ) + { + if( rSprite.is() ) + { + // downcast to derived dxcanvas::Sprite interface, which + // provides the actual redraw methods. + ::boost::polymorphic_downcast< Sprite* >( + rSprite.get() )->redraw(); + } + } + + void spriteRedrawStub2( const ::canvas::SpriteRedrawManager::AreaComponent& rComponent ) + { + if( rComponent.second.getSprite().is() ) + { + // downcast to derived dxcanvas::Sprite interface, which + // provides the actual redraw methods. + ::boost::polymorphic_downcast< Sprite* >( + rComponent.second.getSprite().get() )->redraw(); + } + } + } + + SpriteCanvasHelper::SpriteCanvasHelper() : + mpRedrawManager( NULL ), + mpRenderModule(), + mpSurfaceProxy(), + mpBackBuffer(), + maUpdateRect(), + maScrapRect(), + mbShowSpriteBounds( false ) + { +#if defined(VERBOSE) && defined(DBG_UTIL) + // inverse default for verbose debug mode + mbShowSpriteBounds = true; +#endif + } + + void SpriteCanvasHelper::init( ::canvas::SpriteRedrawManager& rManager, + const IDXRenderModuleSharedPtr& rRenderModule, + const ::canvas::ISurfaceProxyManagerSharedPtr& rSurfaceProxy, + const DXBitmapSharedPtr& rBackBuffer, + const ::basegfx::B2ISize& rOutputOffset ) + { + // init base + setTarget( rBackBuffer, rOutputOffset ); + + mpRedrawManager = &rManager; + mpRenderModule = rRenderModule; + mpSurfaceProxy = rSurfaceProxy; + mpBackBuffer = rBackBuffer; + } + + void SpriteCanvasHelper::disposing() + { + if(mpRenderModule) + mpRenderModule->disposing(); + + mpBackBuffer.reset(); + mpRenderModule.reset(); + mpRedrawManager = NULL; + + // forward to base + CanvasHelper::disposing(); + } + + uno::Reference< rendering::XAnimatedSprite > SpriteCanvasHelper::createSpriteFromAnimation( + const uno::Reference< rendering::XAnimation >& /*animation*/ ) + { + return uno::Reference< rendering::XAnimatedSprite >(); + } + + uno::Reference< rendering::XAnimatedSprite > SpriteCanvasHelper::createSpriteFromBitmaps( + const uno::Sequence< uno::Reference< rendering::XBitmap > >& /*animationBitmaps*/, + sal_Int8 /*interpolationMode*/ ) + { + return uno::Reference< rendering::XAnimatedSprite >(); + } + + uno::Reference< rendering::XCustomSprite > SpriteCanvasHelper::createCustomSprite( const geometry::RealSize2D& spriteSize ) + { + if( !mpRedrawManager ) + return uno::Reference< rendering::XCustomSprite >(); // we're disposed + + return uno::Reference< rendering::XCustomSprite >( + new CanvasCustomSprite( spriteSize, + mpDevice, + mpRenderModule, + mpSurfaceProxy, + mbShowSpriteBounds ) ); + } + + uno::Reference< rendering::XSprite > SpriteCanvasHelper::createClonedSprite( const uno::Reference< rendering::XSprite >& /*original*/ ) + { + return uno::Reference< rendering::XSprite >(); + } + + sal_Bool SpriteCanvasHelper::updateScreen( const ::basegfx::B2IRectangle& rCurrArea, + sal_Bool bUpdateAll, + bool& io_bSurfaceDirty ) + { + if( !mpRedrawManager || + !mpRenderModule || + !mpBackBuffer ) + { + return sal_False; // disposed, or otherwise dysfunctional + } + + // store current output area (need to tunnel that to the + // background, scroll, opaque and general sprite repaint + // routines) + maScrapRect = rCurrArea; + + // clear area that needs to be blitted to screen beforehand + maUpdateRect.reset(); + + // TODO(P1): Might be worthwile to track areas of background + // changes, too. + + // TODO(P2): Might be worthwhile to use page-flipping only if + // a certain percentage of screen area has changed - and + // compose directly to the front buffer otherwise. + if( !bUpdateAll && !io_bSurfaceDirty ) + { + // background has not changed, so we're free to optimize + // repaint to areas where a sprite has changed + + // process each independent area of overlapping sprites + // separately. + mpRedrawManager->forEachSpriteArea( *this ); + + // flip primary surface to screen + // ============================== + + // perform buffer flipping + mpRenderModule->flip( maUpdateRect, + rCurrArea ); + } + else + { + // limit update to parent window area (ignored for fullscreen) + // TODO(E1): Use numeric_cast to catch overflow here + const ::basegfx::B2IRectangle aUpdateArea( 0,0, + static_cast<sal_Int32>(rCurrArea.getWidth()), + static_cast<sal_Int32>(rCurrArea.getHeight()) ); + + // background has changed, or called requested full + // update, or we're performing double buffering via page + // flipping, so we currently have no choice but repaint + // everything + + // repaint the whole screen with background content + mpBackBuffer->draw(aUpdateArea); + + // redraw sprites + mpRedrawManager->forEachSprite(::std::ptr_fun( &spriteRedraw ) ); + + // flip primary surface to screen + // ============================== + + // perform buffer flipping + mpRenderModule->flip( aUpdateArea, + rCurrArea ); + } + + // change record vector must be cleared, for the next turn of + // rendering and sprite changing + mpRedrawManager->clearChangeRecords(); + + io_bSurfaceDirty = false; + + return sal_True; + } + + void SpriteCanvasHelper::backgroundPaint( const ::basegfx::B2DRange& rUpdateRect ) + { + ENSURE_AND_THROW( mpRenderModule && + mpBackBuffer, + "SpriteCanvasHelper::backgroundPaint(): NULL device pointer " ); + + repaintBackground( rUpdateRect, + maScrapRect, + mpBackBuffer ); + } + + void SpriteCanvasHelper::scrollUpdate( const ::basegfx::B2DRange& /*rMoveStart*/, + const ::basegfx::B2DRange& rMoveEnd, + const ::canvas::SpriteRedrawManager::UpdateArea& rUpdateArea ) + { + ENSURE_AND_THROW( mpRenderModule && + mpBackBuffer, + "SpriteCanvasHelper::scrollUpdate(): NULL device pointer " ); + + // round rectangles to integer pixel. Note: have to be + // extremely careful here, to avoid off-by-one errors for + // the destination area: otherwise, the next scroll update + // would copy pixel that are not supposed to be part of + // the sprite. + const ::basegfx::B2IRange& rDestRect( + ::canvas::tools::spritePixelAreaFromB2DRange( rMoveEnd ) ); + + // not much sense in really implementing scrollUpdate here, + // since outputting a sprite only partially would result in + // expensive clipping. Furthermore, we cannot currently render + // 3D directly to the front buffer, thus, would have to blit + // the full sprite area, anyway. But at least optimized in the + // sense that unnecessary background paints behind the sprites + // are avoided. + ::std::for_each( rUpdateArea.maComponentList.begin(), + rUpdateArea.maComponentList.end(), + ::std::ptr_fun( &spriteRedrawStub2 ) ); + + // repaint uncovered areas from backbuffer - take the + // _rounded_ rectangles from above, to have the update + // consistent with the scroll above. + ::std::vector< ::basegfx::B2DRange > aUncoveredAreas; + ::basegfx::computeSetDifference( aUncoveredAreas, + rUpdateArea.maTotalBounds, + ::basegfx::B2DRange( rDestRect ) ); + ::std::for_each( aUncoveredAreas.begin(), + aUncoveredAreas.end(), + ::boost::bind( &repaintBackground, + _1, + ::boost::cref(maScrapRect), + ::boost::cref(mpBackBuffer) ) ); + + // TODO(E1): Use numeric_cast to catch overflow here + ::basegfx::B2IRange aActualArea( 0, 0, + static_cast<sal_Int32>(maScrapRect.getWidth()), + static_cast<sal_Int32>(maScrapRect.getHeight()) ); + aActualArea.intersect( fround( rUpdateArea.maTotalBounds ) ); + + // add given update area to the 'blit to foreground' rect + maUpdateRect.expand( aActualArea ); + } + + void SpriteCanvasHelper::opaqueUpdate( const ::basegfx::B2DRange& rTotalArea, + const ::std::vector< ::canvas::Sprite::Reference >& rSortedUpdateSprites ) + { + ENSURE_AND_THROW( mpRenderModule && + mpBackBuffer, + "SpriteCanvasHelper::opaqueUpdate(): NULL device pointer " ); + + // TODO(P2): optimize this by truly rendering to the front + // buffer. Currently, we've the 3D device only for the back + // buffer. + ::std::for_each( rSortedUpdateSprites.begin(), + rSortedUpdateSprites.end(), + ::std::ptr_fun( &spriteRedrawStub ) ); + + // TODO(E1): Use numeric_cast to catch overflow here + ::basegfx::B2IRange aActualArea( 0, 0, + static_cast<sal_Int32>(maScrapRect.getWidth()), + static_cast<sal_Int32>(maScrapRect.getHeight()) ); + aActualArea.intersect( fround( rTotalArea ) ); + + // add given update area to the 'blit to foreground' rect + maUpdateRect.expand( aActualArea ); + } + + void SpriteCanvasHelper::genericUpdate( const ::basegfx::B2DRange& rTotalArea, + const ::std::vector< ::canvas::Sprite::Reference >& rSortedUpdateSprites ) + { + ENSURE_AND_THROW( mpRenderModule && + mpBackBuffer, + "SpriteCanvasHelper::genericUpdate(): NULL device pointer " ); + + // paint background + // ================ + + // TODO(E1): Use numeric_cast to catch overflow here + ::basegfx::B2IRange aActualArea( 0, 0, + static_cast<sal_Int32>(maScrapRect.getWidth()), + static_cast<sal_Int32>(maScrapRect.getHeight()) ); + aActualArea.intersect( fround( rTotalArea ) ); + + // repaint the given area of the screen with background content + mpBackBuffer->draw(aActualArea); + + // paint sprite + // ============ + + ::std::for_each( rSortedUpdateSprites.begin(), + rSortedUpdateSprites.end(), + ::std::ptr_fun( &spriteRedrawStub ) ); + + // add given update area to the 'blit to foreground' rect + maUpdateRect.expand( aActualArea ); + } +} diff --git a/canvas/source/directx/dx_spritecanvashelper.hxx b/canvas/source/directx/dx_spritecanvashelper.hxx new file mode 100755 index 000000000000..7cb73db380ca --- /dev/null +++ b/canvas/source/directx/dx_spritecanvashelper.hxx @@ -0,0 +1,165 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_spritecanvashelper.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:57:33 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _DXCANVAS_SPRITECANVASHELPER_HXX_ +#define _DXCANVAS_SPRITECANVASHELPER_HXX_ + +#include <com/sun/star/rendering/XSpriteCanvas.hpp> +#include <com/sun/star/rendering/XIntegerBitmap.hpp> + +#include <canvas/spriteredrawmanager.hxx> + +#include "dx_canvashelper.hxx" +#include "dx_impltools.hxx" +#include "dx_rendermodule.hxx" +#include "dx_bitmap.hxx" + +#ifndef _BGFX_RANGE_B2IRECTANGLE_HXX +#include <basegfx/range/b2irectangle.hxx> +#endif + +namespace dxcanvas +{ + class SpriteCanvas; + + class SpriteCanvasHelper : public CanvasHelper + { + public: + SpriteCanvasHelper(); + + void init( ::canvas::SpriteRedrawManager& rManager, + const IDXRenderModuleSharedPtr& rRenderModule, + const ::canvas::ISurfaceProxyManagerSharedPtr& rSurfaceProxy, + const DXBitmapSharedPtr& rBackBuffer, + const ::basegfx::B2ISize& rOutputOffset ); + + /// Dispose all internal references + void disposing(); + + // XSpriteCanvas + ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XAnimatedSprite > createSpriteFromAnimation( + const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XAnimation >& animation ); + + ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XAnimatedSprite > createSpriteFromBitmaps( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XBitmap > >& animationBitmaps, + sal_Int8 interpolationMode ); + + ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XCustomSprite > createCustomSprite( + const ::com::sun::star::geometry::RealSize2D& spriteSize ); + + ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XSprite > createClonedSprite( + const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XSprite >& original ); + + /** Actually perform the screen update + + @param rCurrArea + Current window area in absolute screen coordinates + + @param bUpdateAll + sal_True, if everything must be updated, not only changed + sprites + + @param io_bSurfaceDirty + In/out parameter, whether backbuffer surface is dirty (if + yes, we're performing a full update, anyway) + */ + sal_Bool updateScreen( const ::basegfx::B2IRectangle& rCurrArea, + sal_Bool bUpdateAll, + bool& io_bSurfaceDirty ); + + + // SpriteRedrawManager functor calls + // ------------------------------------------------- + + /** Gets called for simple background repaints + */ + void backgroundPaint( const ::basegfx::B2DRange& rUpdateRect ); + + /** Gets called when area can be handled by scrolling. + + Called method must copy screen content from rMoveStart to + rMoveEnd, and restore the background in the uncovered + areas. + + @param rMoveStart + Source rect of the scroll + + @param rMoveEnd + Dest rect of the scroll + + @param rUpdateArea + All info necessary, should rMoveStart be partially or + fully outside the outdev + */ + void scrollUpdate( const ::basegfx::B2DRange& rMoveStart, + const ::basegfx::B2DRange& rMoveEnd, + const ::canvas::SpriteRedrawManager::UpdateArea& rUpdateArea ); + + void opaqueUpdate( const ::basegfx::B2DRange& rTotalArea, + const ::std::vector< ::canvas::Sprite::Reference >& rSortedUpdateSprites ); + + void genericUpdate( const ::basegfx::B2DRange& rTotalArea, + const ::std::vector< ::canvas::Sprite::Reference >& rSortedUpdateSprites ); + + private: + /// Set from the SpriteCanvas: instance coordinating sprite redraw + ::canvas::SpriteRedrawManager* mpRedrawManager; + + /// DX device, handling all low-level rendering + IDXRenderModuleSharedPtr mpRenderModule; + + ::canvas::ISurfaceProxyManagerSharedPtr mpSurfaceProxy; + + /// Backbuffer, contains the static canvas render output + DXBitmapSharedPtr mpBackBuffer; + + /// Completely temporary rect storage (used by sprite repaint) + mutable ::basegfx::B2IRange maUpdateRect; + + /// Completely temporary rect storage (used by sprite repaint) + mutable ::basegfx::B2IRange maScrapRect; + + /// When true, show small bound rects around each sprite + bool mbShowSpriteBounds; + }; +} + +#endif /* _DXCANVAS_SPRITECANVASHELPER_HXX_ */ diff --git a/canvas/source/directx/dx_spritehelper.cxx b/canvas/source/directx/dx_spritehelper.cxx new file mode 100755 index 000000000000..315b66d111aa --- /dev/null +++ b/canvas/source/directx/dx_spritehelper.cxx @@ -0,0 +1,221 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_spritehelper.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:57:52 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <ctype.h> // don't ask. msdev breaks otherwise... +#include <canvas/debug.hxx> +#include <canvas/verbosetrace.hxx> + +#include <rtl/logfile.hxx> +#include <rtl/math.hxx> + +#include <canvas/canvastools.hxx> + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygonrasterconverter.hxx> +#include <basegfx/polygon/b2dpolygontriangulator.hxx> +#include <basegfx/polygon/b2dpolygoncutandtouch.hxx> + +#include "dx_canvascustomsprite.hxx" +#include "dx_spritehelper.hxx" +#include "dx_impltools.hxx" +#include "dx_surfacegraphics.hxx" + +#include <memory> + +using namespace ::com::sun::star; + +namespace dxcanvas +{ + SpriteHelper::SpriteHelper() : + mpSpriteCanvas(), + mpBitmap(), + mbTextureDirty( true ), + mbShowSpriteBounds( false ) + { + } + + void SpriteHelper::init( const geometry::RealSize2D& rSpriteSize, + const SpriteCanvasRef& rSpriteCanvas, + const IDXRenderModuleSharedPtr& rRenderModule, + const DXBitmapSharedPtr rBitmap, + bool bShowSpriteBounds ) + { + ENSURE_AND_THROW( rSpriteCanvas.get() && + rRenderModule && + rBitmap, + "SpriteHelper::init(): Invalid device, sprite canvas or surface" ); + + mpSpriteCanvas = rSpriteCanvas; + mpBitmap = rBitmap; + mbTextureDirty = true; + mbShowSpriteBounds = bShowSpriteBounds; + + // also init base class + CanvasCustomSpriteHelper::init( rSpriteSize, + rSpriteCanvas.get() ); + } + + void SpriteHelper::disposing() + { + mpBitmap.reset(); + mpSpriteCanvas.clear(); + + // forward to parent + CanvasCustomSpriteHelper::disposing(); + } + + ::basegfx::B2DPolyPolygon SpriteHelper::polyPolygonFromXPolyPolygon2D( uno::Reference< rendering::XPolyPolygon2D >& xPoly ) const + { + return tools::polyPolygonFromXPolyPolygon2D( xPoly ); + } + + bool SpriteHelper::needRedraw() const + { + if( !mpBitmap || + !mpSpriteCanvas.get() ) + { + return false; // we're disposed, no redraw necessary + } + + if( !isActive() || + ::basegfx::fTools::equalZero( getAlpha() ) ) + { + return false; // sprite is invisible + } + + return true; + } + + void SpriteHelper::redraw( bool& io_bSurfaceDirty ) const + { + if( !mpBitmap || + !mpSpriteCanvas.get() ) + { + return; // we're disposed + } + + const ::basegfx::B2DPoint& rPos( getPosPixel() ); + const double fAlpha( getAlpha() ); + + if( isActive() && + !::basegfx::fTools::equalZero( fAlpha ) ) + { + + // TODO(Q2): For the time being, Device does not take a target + // surface, but always unconditionally renders to the + // background buffer. + + // log output pos in device pixel + VERBOSE_TRACE( "SpriteHelper::redraw(): output pos is (%f, %f)", + rPos.getX(), + rPos.getY() ); + + const double fAlpha( getAlpha() ); + const ::basegfx::B2DVector& rSize( getSizePixel() ); + const ::basegfx::B2DHomMatrix& rTransform( getTransformation() ); + const uno::Reference< rendering::XPolyPolygon2D >& xClip( getClip() ); + + mbTextureDirty = false; + io_bSurfaceDirty = false; // state taken, and processed. + + ::basegfx::B2DPolyPolygon aClipPath; // empty for no clip + bool bIsClipRectangular( false ); // false, if no + // clip, or clip + // is complex + + // setup and apply clip (if any) + // ================================= + + if( xClip.is() ) + { + aClipPath = tools::polyPolygonFromXPolyPolygon2D( xClip ); + + const sal_Int32 nNumClipPolygons( aClipPath.count() ); + if( nNumClipPolygons ) + { + // TODO(P2): hold rectangle attribute directly + // at the XPolyPolygon2D + + // check whether the clip is rectangular + if( nNumClipPolygons == 1 ) + if( ::basegfx::tools::isRectangle( aClipPath.getB2DPolygon( 0 ) ) ) + bIsClipRectangular = true; + } + } + + const ::basegfx::B2DRectangle aSourceRect( 0.0, + 0.0, + rSize.getX(), + rSize.getY() ); + + // draw simple rectangular area if no clip is set. + if( !aClipPath.count() ) + { + mpBitmap->draw(fAlpha,rPos,rTransform); + } + else if( bIsClipRectangular ) + { + // apply a simple rect clip + // ======================== + + ::basegfx::B2DRectangle aClipBounds( + ::basegfx::tools::getRange( aClipPath ) ); + aClipBounds.intersect( aSourceRect ); + + mpBitmap->draw(fAlpha,rPos,aClipBounds,rTransform); + } + else + { + // apply clip the hard way + // ======================= + + mpBitmap->draw(fAlpha,rPos,aClipPath,rTransform); + } + + if( mbShowSpriteBounds ) + { + if( aClipPath.count() ) + { + // TODO(F2): Re-enable debug output + } + } + } + } +} diff --git a/canvas/source/directx/dx_spritehelper.hxx b/canvas/source/directx/dx_spritehelper.hxx new file mode 100755 index 000000000000..1bfe6a1440f0 --- /dev/null +++ b/canvas/source/directx/dx_spritehelper.hxx @@ -0,0 +1,119 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_spritehelper.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:58:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _DXCANVAS_SPRITEHELPER_HXX +#define _DXCANVAS_SPRITEHELPER_HXX + +#include <com/sun/star/rendering/XCustomSprite.hpp> + +#include <canvas/base/canvascustomspritehelper.hxx> + +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/vector/b2isize.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> + +#include "dx_spritecanvas.hxx" +#include "dx_bitmap.hxx" + +namespace dxcanvas +{ + /* Definition of SpriteHelper class */ + + /** Helper class for canvas sprites. + + This class implements all sprite-related functionality, like + that available on the XSprite interface. + */ + class SpriteHelper : public ::canvas::CanvasCustomSpriteHelper + { + public: + /** Create sprite helper + */ + SpriteHelper(); + + /** Late-init the sprite helper + + @param rSpriteSize + Size of the sprite + + @param rSpriteCanvas + Sprite canvas this sprite is part of. Object stores + ref-counted reference to it, thus, don't forget to pass on + disposing()! + + @param rRenderModule + rendermodule to use + + @param rSpriteSurface + The surface of the sprite (not the DX texture, but the + persistent target of content rendering) + + @param bShowSpriteBounds + When true, little debug bound rects for sprites are shown + */ + void init( const ::com::sun::star::geometry::RealSize2D& rSpriteSize, + const SpriteCanvasRef& rSpriteCanvas, + const IDXRenderModuleSharedPtr& rRenderModule, + const DXBitmapSharedPtr rBitmap, + bool bShowSpriteBounds ); + + void disposing(); + + /** Repaint sprite content via hardware to associated sprite + canvas + + @param io_bSurfaceDirty + Input/output parameter, whether the sprite content is + dirty or not. If texture was updated, set to false + + */ + void redraw( bool& io_bSurfaceDirty ) const; + + private: + virtual ::basegfx::B2DPolyPolygon polyPolygonFromXPolyPolygon2D( + ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >& xPoly ) const; + + /// Returns true, if the sprite _really_ needs redraw + bool needRedraw() const; + + SpriteCanvasRef mpSpriteCanvas; + + DXBitmapSharedPtr mpBitmap; + mutable bool mbTextureDirty; // when true, texture needs update + bool mbShowSpriteBounds; // when true, debug bound rect for sprites is shown + }; +} + +#endif /* _DXCANVAS_SPRITEHELPER_HXX */ diff --git a/canvas/source/directx/dx_surfacegraphics.cxx b/canvas/source/directx/dx_surfacegraphics.cxx new file mode 100755 index 000000000000..01606a33bfc4 --- /dev/null +++ b/canvas/source/directx/dx_surfacegraphics.cxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_surfacegraphics.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:58:19 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "dx_impltools.hxx" +#include "dx_surfacegraphics.hxx" +//#include <imdebug.h> + + +namespace dxcanvas +{ + SurfaceGraphics::SurfaceGraphics() : + mpSurface(NULL), + mpGraphics(NULL), + mpBitmap(), + maHDC(0) + { + } + + SurfaceGraphics::SurfaceGraphics( HDC aHDC ) : + mpSurface(NULL), + mpGraphics(NULL), + mpBitmap(), + maHDC(0) + { + mpGraphics = new Gdiplus::Graphics(aHDC); + if(mpGraphics) + tools::setupGraphics( *mpGraphics ); + } + + SurfaceGraphics::SurfaceGraphics( const BitmapSharedPtr& rBitmap ) : + mpSurface(NULL), + mpGraphics(NULL), + mpBitmap(rBitmap), + maHDC(0) + { + mpGraphics = Gdiplus::Graphics::FromImage(mpBitmap.get()); + + if(mpGraphics) + tools::setupGraphics( *mpGraphics ); + } + + SurfaceGraphics::SurfaceGraphics( const COMReference<surface_type>& rSurface ) : + mpSurface(rSurface), + mpGraphics(NULL), + mpBitmap(), + maHDC(0) + { + if( SUCCEEDED(mpSurface->GetDC( &maHDC )) ) + { + mpGraphics = Gdiplus::Graphics::FromHDC( maHDC ); + if(mpGraphics) + { + tools::setupGraphics( *mpGraphics ); + return; + } + + mpSurface->ReleaseDC( maHDC ); + } + } + + SurfaceGraphics::~SurfaceGraphics() + { + if(!(mpGraphics)) + return; + + mpGraphics->Flush(Gdiplus::FlushIntentionSync); + delete mpGraphics; + + if(mpSurface.is()) + mpSurface->ReleaseDC( maHDC ); + } +} diff --git a/canvas/source/directx/dx_surfacegraphics.hxx b/canvas/source/directx/dx_surfacegraphics.hxx new file mode 100755 index 000000000000..fed6b4a3a6ea --- /dev/null +++ b/canvas/source/directx/dx_surfacegraphics.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_surfacegraphics.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:58:36 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _DXCANVAS_SURFACEGRAPHICS_HXX +#define _DXCANVAS_SURFACEGRAPHICS_HXX + +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> + +namespace dxcanvas +{ + /** Container providing a Gdiplus::Graphics for a Surface + + This wrapper class transparently handles allocation and + release of surface resources the RAII way. Please don't create + yourself, the only legal way to obtain such an object is via + Surface::getGraphics() + + @see Surface::getGraphics() + */ + class SurfaceGraphics : private ::boost::noncopyable + { + public: + SurfaceGraphics(); + explicit SurfaceGraphics( HDC aHDC ); + explicit SurfaceGraphics( const BitmapSharedPtr& rBitmap ); + explicit SurfaceGraphics( const COMReference<surface_type>& rSurface ); + ~SurfaceGraphics(); + + bool is() const { return mpGraphics != NULL; } + Gdiplus::Graphics* get() { return mpGraphics; } + const Gdiplus::Graphics* get() const { return mpGraphics; } + Gdiplus::Graphics* operator->() { return mpGraphics; } + const Gdiplus::Graphics* operator->() const { return mpGraphics; } + Gdiplus::Graphics& operator*() { return *mpGraphics; } + const Gdiplus::Graphics& operator*() const { return *mpGraphics; } + + private: + COMReference<surface_type> mpSurface; + Gdiplus::Graphics* mpGraphics; + BitmapSharedPtr mpBitmap; + HDC maHDC; + }; + + typedef ::boost::shared_ptr< SurfaceGraphics > SurfaceGraphicsSharedPtr; +} + +#endif /* _DXCANVAS_SURFACEGRAPHICS_HXX */ diff --git a/canvas/source/directx/dx_textlayout.cxx b/canvas/source/directx/dx_textlayout.cxx new file mode 100755 index 000000000000..32e628c9c382 --- /dev/null +++ b/canvas/source/directx/dx_textlayout.cxx @@ -0,0 +1,282 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_textlayout.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:58:47 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <ctype.h> // don't ask. msdev breaks otherwise... +#include <canvas/debug.hxx> +#include <canvas/verbosetrace.hxx> + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/numeric/ftools.hxx> +#include "dx_bitmap.hxx" +#include "dx_textlayout.hxx" +#include "dx_spritecanvas.hxx" +#include "dx_textlayout_drawhelper.hxx" + + +using namespace ::com::sun::star; + +namespace dxcanvas +{ + TextLayout::TextLayout( const rendering::StringContext& aText, + sal_Int8 nDirection, + sal_Int64 /*nRandomSeed*/, + const CanvasFont::ImplRef& rFont ) : + TextLayout_Base( m_aMutex ), + maText( aText ), + maLogicalAdvancements(), + mpFont( rFont ), + mnTextDirection( nDirection ) + { + } + + TextLayout::~TextLayout() + { + } + + void SAL_CALL TextLayout::disposing() + { + mpFont.reset(); + } + + // XTextLayout + uno::Sequence< uno::Reference< rendering::XPolyPolygon2D > > SAL_CALL TextLayout::queryTextShapes( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return uno::Sequence< uno::Reference< rendering::XPolyPolygon2D > >(); + } + + uno::Sequence< geometry::RealRectangle2D > SAL_CALL TextLayout::queryInkMeasures( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return uno::Sequence< geometry::RealRectangle2D >(); + } + + uno::Sequence< geometry::RealRectangle2D > SAL_CALL TextLayout::queryMeasures( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return uno::Sequence< geometry::RealRectangle2D >(); + } + + uno::Sequence< double > SAL_CALL TextLayout::queryLogicalAdvancements( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + return maLogicalAdvancements; + } + + void SAL_CALL TextLayout::applyLogicalAdvancements( const uno::Sequence< double >& aAdvancements ) throw (lang::IllegalArgumentException, uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if( aAdvancements.getLength() != maText.Length ) + { + OSL_TRACE( "TextLayout::applyLogicalAdvancements(): mismatching number of advancements" ); + throw lang::IllegalArgumentException(); + } + + maLogicalAdvancements = aAdvancements; + } + + geometry::RealRectangle2D SAL_CALL TextLayout::queryTextBounds( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Reference< rendering::XGraphicDevice > xGraphicDevice; + ::dxcanvas::TextLayoutDrawHelper aDrawHelper(xGraphicDevice); + + // render text + const geometry::RealRectangle2D aBounds( + aDrawHelper.queryTextBounds( + maText, + maLogicalAdvancements, + mpFont.getRef(), + mpFont->getFontMatrix())); + + return aBounds; + } + + double SAL_CALL TextLayout::justify( double /*nSize*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return 0.0; + } + + double SAL_CALL TextLayout::combinedJustify( const uno::Sequence< uno::Reference< rendering::XTextLayout > >& /*aNextLayouts*/, + double /*nSize*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return 0.0; + } + + rendering::TextHit SAL_CALL TextLayout::getTextHit( const geometry::RealPoint2D& /*aHitPoint*/ ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return rendering::TextHit(); + } + + rendering::Caret SAL_CALL TextLayout::getCaret( sal_Int32 /*nInsertionIndex*/, + sal_Bool /*bExcludeLigatures*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return rendering::Caret(); + } + + sal_Int32 SAL_CALL TextLayout::getNextInsertionIndex( sal_Int32 /*nStartIndex*/, + sal_Int32 /*nCaretAdvancement*/, + sal_Bool /*bExcludeLigatures*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return 0; + } + + uno::Reference< rendering::XPolyPolygon2D > SAL_CALL TextLayout::queryVisualHighlighting( sal_Int32 /*nStartIndex*/, + sal_Int32 /*nEndIndex*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return uno::Reference< rendering::XPolyPolygon2D >(); + } + + uno::Reference< rendering::XPolyPolygon2D > SAL_CALL TextLayout::queryLogicalHighlighting( sal_Int32 /*nStartIndex*/, + sal_Int32 /*nEndIndex*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return uno::Reference< rendering::XPolyPolygon2D >(); + } + + double SAL_CALL TextLayout::getBaselineOffset( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO + return 0.0; + } + + sal_Int8 SAL_CALL TextLayout::getMainTextDirection( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + return mnTextDirection; + } + + uno::Reference< rendering::XCanvasFont > SAL_CALL TextLayout::getFont( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + return mpFont.getRef(); + } + + rendering::StringContext SAL_CALL TextLayout::getText( ) throw (uno::RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + return maText; + } + + namespace + { + // TODO(P2): Check whether this gets inlined. If not, make functor + // out of it + inline Gdiplus::PointF gdiPlusPointFromDx( const double& dx ) + { + return Gdiplus::PointF( static_cast<Gdiplus::REAL>(dx), + 0.0f ); + } + } + + bool TextLayout::draw( const DXBitmapSharedPtr &rBitmap, + const rendering::ViewState& rViewState, + const rendering::RenderState& rRenderState, + const ::basegfx::B2ISize& rOutputOffset, + const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice ) const + { + ::osl::MutexGuard aGuard( m_aMutex ); + + ::dxcanvas::TextLayoutDrawHelper aDrawHelper(xGraphicDevice); + + // render text + aDrawHelper.drawText(rBitmap, + rViewState, + rRenderState, + rOutputOffset, + maText, + maLogicalAdvancements, + mpFont.getRef(), + mpFont->getFontMatrix()); + + return true; + } + + +#define SERVICE_NAME "com.sun.star.rendering.TextLayout" +#define IMPLEMENTATION_NAME "DXCanvas::TextLayout" + + ::rtl::OUString SAL_CALL TextLayout::getImplementationName() throw( uno::RuntimeException ) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) ); + } + + sal_Bool SAL_CALL TextLayout::supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException ) + { + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) ); + } + + uno::Sequence< ::rtl::OUString > SAL_CALL TextLayout::getSupportedServiceNames() throw( uno::RuntimeException ) + { + uno::Sequence< ::rtl::OUString > aRet(1); + aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) ); + + return aRet; + } +} diff --git a/canvas/source/directx/dx_textlayout.hxx b/canvas/source/directx/dx_textlayout.hxx new file mode 100755 index 000000000000..2f7d7a299e89 --- /dev/null +++ b/canvas/source/directx/dx_textlayout.hxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_textlayout.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:59:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _DXCANVAS_TEXTLAYOUT_HXX +#define _DXCANVAS_TEXTLAYOUT_HXX + +#include <cppuhelper/compbase2.hxx> +#include <comphelper/broadcasthelper.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <com/sun/star/rendering/XTextLayout.hpp> + +#include <basegfx/vector/b2isize.hxx> + +#include <boost/utility.hpp> + +#include "dx_canvasfont.hxx" +#include "dx_surfacegraphics.hxx" +#include "dx_winstuff.hxx" +#include "dx_gdiplususer.hxx" + + +/* Definition of TextLayout class */ +class DXBitmapSharedPtr; + +namespace dxcanvas +{ + typedef ::cppu::WeakComponentImplHelper2< ::com::sun::star::rendering::XTextLayout, + ::com::sun::star::lang::XServiceInfo > TextLayout_Base; + + class TextLayout : public ::comphelper::OBaseMutex, + public TextLayout_Base, + private ::boost::noncopyable + { + public: + TextLayout( const ::com::sun::star::rendering::StringContext& aText, + sal_Int8 nDirection, + sal_Int64 nRandomSeed, + const CanvasFont::ImplRef& rFont ); + + /// Dispose all internal references + virtual void SAL_CALL disposing(); + + // XTextLayout + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D > > SAL_CALL queryTextShapes( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealRectangle2D > SAL_CALL queryInkMeasures( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealRectangle2D > SAL_CALL queryMeasures( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< double > SAL_CALL queryLogicalAdvancements( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL applyLogicalAdvancements( const ::com::sun::star::uno::Sequence< double >& aAdvancements ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::geometry::RealRectangle2D SAL_CALL queryTextBounds( ) throw (::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL justify( double nSize ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL combinedJustify( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XTextLayout > >& aNextLayouts, double nSize ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::rendering::TextHit SAL_CALL getTextHit( const ::com::sun::star::geometry::RealPoint2D& aHitPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::rendering::Caret SAL_CALL getCaret( sal_Int32 nInsertionIndex, sal_Bool bExcludeLigatures ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getNextInsertionIndex( sal_Int32 nStartIndex, sal_Int32 nCaretAdvancement, sal_Bool bExcludeLigatures ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D > SAL_CALL queryVisualHighlighting( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D > SAL_CALL queryLogicalHighlighting( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL getBaselineOffset( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int8 SAL_CALL getMainTextDirection( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvasFont > SAL_CALL getFont( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::rendering::StringContext SAL_CALL getText( ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ); + + bool draw( const DXBitmapSharedPtr& rBitmap, + const ::com::sun::star::rendering::ViewState& rViewState, + const ::com::sun::star::rendering::RenderState& rRenderState, + const ::basegfx::B2ISize& rOutputOffset, + const ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XGraphicDevice >& xGraphicDevice ) const; + + protected: + ~TextLayout(); // we're a ref-counted UNO class. _We_ destroy ourselves. + + private: + // NOTE: no need for GDIPlusUserSharedPtr, mpFont implicitely has one already + + ::com::sun::star::rendering::StringContext maText; + ::com::sun::star::uno::Sequence< double > maLogicalAdvancements; + CanvasFont::ImplRef mpFont; + sal_Int8 mnTextDirection; + }; + +} + +#endif /* _DXCANVAS_TEXTLAYOUT_HXX */ diff --git a/canvas/source/directx/dx_textlayout_drawhelper.cxx b/canvas/source/directx/dx_textlayout_drawhelper.cxx new file mode 100755 index 000000000000..081b06efdb56 --- /dev/null +++ b/canvas/source/directx/dx_textlayout_drawhelper.cxx @@ -0,0 +1,313 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_textlayout_drawhelper.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:59:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <tools/poly.hxx> + +#include <vcl/metric.hxx> +#include <vcl/virdev.hxx> +#include <vcl/metric.hxx> +#include <vcl/canvastools.hxx> + +#include <boost/scoped_array.hpp> +#include <boost/bind.hpp> +#include <com/sun/star/rendering/FontRequest.hpp> +#include <com/sun/star/rendering/XCanvasFont.hpp> +#include <comphelper/sequence.hxx> +#include <comphelper/scopeguard.hxx> +#include <tools/color.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <canvas/canvastools.hxx> +#include <canvas/debug.hxx> +#include "dx_impltools.hxx" +#include <vcl/sysdata.hxx> +#include "dx_surfacegraphics.hxx" +#include "dx_textlayout_drawhelper.hxx" +#include "dx_bitmap.hxx" +#include "dx_canvasfont.hxx" + +class ::com::sun::star::rendering::XCanvasFont; + +using namespace ::com::sun::star; + + +////////////////////////////////////////////////////////////////////////////// + +namespace dxcanvas +{ + class DXBitmap; + TextLayoutDrawHelper::TextLayoutDrawHelper( + const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice ) : + mxGraphicDevice(xGraphicDevice) + { + } + + TextLayoutDrawHelper::~TextLayoutDrawHelper() + { + } + + void TextLayoutDrawHelper::drawText( const ::boost::shared_ptr< dxcanvas::DXBitmap > &rBitmap, + const ::com::sun::star::rendering::ViewState& rViewState, + const ::com::sun::star::rendering::RenderState& rRenderState, + const ::basegfx::B2ISize& rOutputOffset, + const ::com::sun::star::rendering::StringContext& rText, + const ::com::sun::star::uno::Sequence< double >& rLogicalAdvancements, + const ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XCanvasFont >& rCanvasFont, + const ::com::sun::star::geometry::Matrix2D& rFontMatrix ) + { + SurfaceGraphicsSharedPtr graphics(rBitmap->getGraphics()); + HDC hdc = (*graphics)->GetHDC(); + + // issue an ReleaseHDC() when leaving the scope + const ::comphelper::ScopeGuard aGuard( + boost::bind( &Gdiplus::Graphics::ReleaseHDC, + graphics->get(), + hdc )); + + SystemGraphicsData aSystemGraphicsData; + aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); + aSystemGraphicsData.hDC = reinterpret_cast< ::HDC >(hdc); + VirtualDevice aVirtualDevice(&aSystemGraphicsData, 0); + + // disable font antialiasing - GDI does not handle alpha + // surfaces properly. + if( rBitmap->hasAlpha() ) + aVirtualDevice.SetAntialiasing(ANTIALIASING_DISABLE_TEXT); + + if(rText.Length) + { + sal_Bool test = mxGraphicDevice.is(); + ENSURE_AND_THROW( test, + "TextLayoutDrawHelper::drawText(): Invalid GraphicDevice" ); + + // set text color. Make sure to remove transparence part first. + Color aColor( COL_WHITE ); + + if( rRenderState.DeviceColor.getLength() > 2 ) + aColor = ::vcl::unotools::sequenceToColor(mxGraphicDevice, + rRenderState.DeviceColor); + aColor.SetTransparency(0); + aVirtualDevice.SetTextColor(aColor); + + // create the font + const ::com::sun::star::rendering::FontRequest& rFontRequest = rCanvasFont->getFontRequest(); + Font aFont( + rFontRequest.FontDescription.FamilyName, + rFontRequest.FontDescription.StyleName, + Size( 0, ::basegfx::fround(rFontRequest.CellSize))); + + aFont.SetAlign( ALIGN_BASELINE ); + aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==com::sun::star::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); + aFont.SetVertical( (rFontRequest.FontDescription.IsVertical==com::sun::star::util::TriState_YES) ? TRUE : FALSE ); + aFont.SetWeight( static_cast<FontWeight>(rFontRequest.FontDescription.FontDescription.Weight) ); + aFont.SetItalic( (rFontRequest.FontDescription.FontDescription.Letterform<=8) ? ITALIC_NONE : ITALIC_NORMAL ); + + // setup font color + aFont.SetColor( aColor ); + aFont.SetFillColor( aColor ); + + // adjust to stretched font + if(!::rtl::math::approxEqual(rFontMatrix.m00, rFontMatrix.m11)) + { + const Size aSize = aVirtualDevice.GetFontMetric( aFont ).GetSize(); + const double fDividend( rFontMatrix.m10 + rFontMatrix.m11 ); + double fStretch = (rFontMatrix.m00 + rFontMatrix.m01); + + if( !::basegfx::fTools::equalZero( fDividend) ) + fStretch /= fDividend; + + const sal_Int32 nNewWidth = ::basegfx::fround( aSize.Width() * fStretch ); + + aFont.SetWidth( nNewWidth ); + } + + // set font + aVirtualDevice.SetFont(aFont); + + // create world transformation matrix + ::basegfx::B2DHomMatrix aWorldTransform; + ::canvas::tools::mergeViewAndRenderTransform(aWorldTransform, rViewState, rRenderState); + + if(!rOutputOffset.equalZero()) + { + aWorldTransform.translate(rOutputOffset.getX(), rOutputOffset.getY()); + } + + // set ViewState clipping + if(rViewState.Clip.is()) + { + ::basegfx::B2DPolyPolygon aClipPoly(dxcanvas::tools::polyPolygonFromXPolyPolygon2D(rViewState.Clip)); + ::basegfx::B2DHomMatrix aMatrix; + ::basegfx::unotools::homMatrixFromAffineMatrix(aMatrix, rViewState.AffineTransform ); + + if(!rOutputOffset.equalZero()) + { + aMatrix.translate(rOutputOffset.getX(), rOutputOffset.getY()); + } + + aClipPoly.transform(aMatrix); + const Region& rClipRegion = Region(PolyPolygon(aClipPoly)); + aVirtualDevice.IntersectClipRegion(rClipRegion); + } + + if(rRenderState.Clip.is()) + { + ::basegfx::B2DPolyPolygon aClipPoly(dxcanvas::tools::polyPolygonFromXPolyPolygon2D(rRenderState.Clip)); + aClipPoly.transform(aWorldTransform); + const Region& rClipRegion = Region(PolyPolygon(aClipPoly)); + aVirtualDevice.IntersectClipRegion(rClipRegion); + } + + // set world transform + XFORM aXForm; + aXForm.eM11 = (FLOAT)aWorldTransform.get(0, 0); + aXForm.eM12 = (FLOAT)aWorldTransform.get(1, 0); + aXForm.eM21 = (FLOAT)aWorldTransform.get(0, 1); + aXForm.eM22 = (FLOAT)aWorldTransform.get(1, 1); + aXForm.eDx = (FLOAT)aWorldTransform.get(0, 2); + aXForm.eDy = (FLOAT)aWorldTransform.get(1, 2); + + // TODO(F3): This is NOT supported on 95/98/ME! + //win32::HDC aHDC(rBitmap->getHDC()); + SetGraphicsMode(hdc, GM_ADVANCED); + SetTextAlign(hdc, TA_BASELINE); + SetWorldTransform(hdc, &aXForm); + + // use a empty StartPosition for text rendering + const Point aEmptyPoint(0, 0); + + // create the String + const String aText(rText.Text.getStr()); + + if( rLogicalAdvancements.getLength() ) + { + // create the DXArray + const sal_Int32 nLen( rLogicalAdvancements.getLength() ); + ::boost::scoped_array<sal_Int32> pDXArray( new sal_Int32[nLen] ); + for( sal_Int32 i=0; i<nLen; ++i ) + pDXArray[i] = basegfx::fround( rLogicalAdvancements[i] ); + + // draw the String + aVirtualDevice.DrawTextArray( aEmptyPoint, + aText, + pDXArray.get(), + (xub_StrLen)rText.StartPosition, + (xub_StrLen)rText.Length ); + } + else + { + // draw the String + aVirtualDevice.DrawText( aEmptyPoint, + aText, + (xub_StrLen)rText.StartPosition, + (xub_StrLen)rText.Length ); + } + } + } + + geometry::RealRectangle2D TextLayoutDrawHelper::queryTextBounds( const rendering::StringContext& rText, + const uno::Sequence< double >& rLogicalAdvancements, + const uno::Reference< rendering::XCanvasFont >& rCanvasFont, + const geometry::Matrix2D& rFontMatrix ) + { + if(!(rText.Length)) + return geometry::RealRectangle2D(); + + // TODO(F1): Fetching default screen DC here, will yield wrong + // metrics when e.g. formatting for a printer! + SystemGraphicsData aSystemGraphicsData; + aSystemGraphicsData.nSize = sizeof(SystemGraphicsData); + aSystemGraphicsData.hDC = reinterpret_cast< ::HDC >(GetDC( NULL )); + VirtualDevice aVirtualDevice(&aSystemGraphicsData, 0); + + // create the font + const ::com::sun::star::rendering::FontRequest& rFontRequest = rCanvasFont->getFontRequest(); + Font aFont( + rFontRequest.FontDescription.FamilyName, + rFontRequest.FontDescription.StyleName, + Size( 0, ::basegfx::fround(rFontRequest.CellSize))); + + aFont.SetAlign( ALIGN_BASELINE ); + aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==com::sun::star::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); + aFont.SetVertical( (rFontRequest.FontDescription.IsVertical==com::sun::star::util::TriState_YES) ? TRUE : FALSE ); + aFont.SetWeight( static_cast<FontWeight>(rFontRequest.FontDescription.FontDescription.Weight) ); + aFont.SetItalic( (rFontRequest.FontDescription.FontDescription.Letterform<=8) ? ITALIC_NONE : ITALIC_NORMAL ); + + // adjust to stretched font + if(!::rtl::math::approxEqual(rFontMatrix.m00, rFontMatrix.m11)) + { + const Size aSize = aVirtualDevice.GetFontMetric( aFont ).GetSize(); + const double fDividend( rFontMatrix.m10 + rFontMatrix.m11 ); + double fStretch = (rFontMatrix.m00 + rFontMatrix.m01); + + if( !::basegfx::fTools::equalZero( fDividend) ) + fStretch /= fDividend; + + const sal_Int32 nNewWidth = ::basegfx::fround( aSize.Width() * fStretch ); + + aFont.SetWidth( nNewWidth ); + } + + // set font + aVirtualDevice.SetFont(aFont); + + // need metrics for Y offset, the XCanvas always renders + // relative to baseline + const ::FontMetric& aMetric( aVirtualDevice.GetFontMetric() ); + + const sal_Int32 nAboveBaseline( -aMetric.GetIntLeading() - aMetric.GetAscent() ); + const sal_Int32 nBelowBaseline( aMetric.GetDescent() ); + + if( rLogicalAdvancements.getLength() ) + { + return geometry::RealRectangle2D( 0, nAboveBaseline, + rLogicalAdvancements[ rLogicalAdvancements.getLength()-1 ], + nBelowBaseline ); + } + else + { + return geometry::RealRectangle2D( 0, nAboveBaseline, + aVirtualDevice.GetTextWidth( + rText.Text, + ::canvas::tools::numeric_cast<USHORT>(rText.StartPosition), + ::canvas::tools::numeric_cast<USHORT>(rText.Length) ), + nBelowBaseline ); + } + } +} + + +// eof diff --git a/canvas/source/directx/dx_textlayout_drawhelper.hxx b/canvas/source/directx/dx_textlayout_drawhelper.hxx new file mode 100755 index 000000000000..3bf610c614c0 --- /dev/null +++ b/canvas/source/directx/dx_textlayout_drawhelper.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_textlayout_drawhelper.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:59:39 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _TEXTLAYOUT_DRAWHELPER_HXX +#define _TEXTLAYOUT_DRAWHELPER_HXX + +#include <boost/shared_ptr.hpp> + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/rendering/StringContext.hpp> +#include <com/sun/star/rendering/XCanvasFont.hpp> +#include <com/sun/star/geometry/Matrix2D.hpp> +#include <com/sun/star/rendering/XGraphicDevice.hpp> + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/vector/b2isize.hxx> + +class ::com::sun::star::rendering::XCanvasFont; + +namespace dxcanvas +{ + class DXBitmap; + class TextLayoutDrawHelper + { + public: + TextLayoutDrawHelper( + const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XGraphicDevice >& xGraphicDevice); + ~TextLayoutDrawHelper(); + + // draw text + void drawText( const ::boost::shared_ptr< DXBitmap > &rBitmap, + const ::com::sun::star::rendering::ViewState& rViewState, + const ::com::sun::star::rendering::RenderState& rRenderState, + const ::basegfx::B2ISize& rOutputOffset, + const ::com::sun::star::rendering::StringContext& rText, + const ::com::sun::star::uno::Sequence< double >& rLogicalAdvancements, + const ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XCanvasFont >& rCanvasFont, + const ::com::sun::star::geometry::Matrix2D& rFontMatrix ); + + ::com::sun::star::geometry::RealRectangle2D queryTextBounds( + const ::com::sun::star::rendering::StringContext& rText, + const ::com::sun::star::uno::Sequence< double >& rLogicalAdvancements, + const ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XCanvasFont >& rCanvasFont, + const ::com::sun::star::geometry::Matrix2D& rFontMatrix ); + +#ifdef DBG_UTIL + void test(); +#endif + + protected: + ::com::sun::star::uno::Reference< + ::com::sun::star::rendering::XGraphicDevice > mxGraphicDevice; + }; +} + +#endif /* _TEXTLAYOUT_DRAWHELPER_HXX */ +// eof diff --git a/canvas/source/directx/dx_vcltools.cxx b/canvas/source/directx/dx_vcltools.cxx new file mode 100755 index 000000000000..d9c8a29076a7 --- /dev/null +++ b/canvas/source/directx/dx_vcltools.cxx @@ -0,0 +1,553 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_vcltools.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 17:59:58 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <vcl/canvastools.hxx> + +#include <vcl/bitmap.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/bmpacc.hxx> + +#include "dx_impltools.hxx" +#include <basegfx/numeric/ftools.hxx> + +#include <canvas/debug.hxx> +#include <canvas/verbosetrace.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> + + +#include <boost/scoped_array.hpp> + +#include "dx_vcltools.hxx" + +using namespace ::com::sun::star; + +namespace dxcanvas +{ + namespace tools + { + namespace + { + /// Calc number of colors in given BitmapInfoHeader + sal_Int32 calcDIBColorCount( const BITMAPINFOHEADER& rBIH ) + { + if( rBIH.biSize != sizeof( BITMAPCOREHEADER ) ) + { + if( rBIH.biBitCount <= 8 ) + { + if( rBIH.biClrUsed ) + return rBIH.biClrUsed; + else + return 1L << rBIH.biBitCount; + } + } + else + { + BITMAPCOREHEADER* pCoreHeader = (BITMAPCOREHEADER*)&rBIH; + + if( pCoreHeader->bcBitCount <= 8 ) + return 1L << pCoreHeader->bcBitCount; + } + + return 0; // nothing known + } + + /// Draw DI bits to given Graphics + bool drawDIBits( const ::boost::shared_ptr< SurfaceGraphics >& rGraphics, + const void* hDIB ) + { + bool bRet( false ); + BitmapSharedPtr pBitmap; + + const BITMAPINFO* pBI = (BITMAPINFO*)GlobalLock( (HGLOBAL)hDIB ); + + if( pBI ) + { + const BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*)pBI; + const BYTE* pBits = (BYTE*) pBI + *(DWORD*)pBI + + calcDIBColorCount( *pBIH ) * sizeof( RGBQUAD ); + + // forward to outsourced GDI+ rendering method + // (header clashes) + bRet = tools::drawDIBits( rGraphics, *pBI, (void*)pBits ); + + GlobalUnlock( (HGLOBAL)hDIB ); + } + + return bRet; + } + + /** Draw VCL bitmap to given Graphics + + @param rBmp + Reference to bitmap. Might get modified, in such a way + that it will hold a DIB after a successful function call. + */ + bool drawVCLBitmap( const ::boost::shared_ptr< SurfaceGraphics >& rGraphics, + ::Bitmap& rBmp ) + { + BitmapSystemData aBmpSysData; + + if( !rBmp.GetSystemData( aBmpSysData ) || + !aBmpSysData.pDIB ) + { + // first of all, ensure that Bitmap contains a DIB, by + // aquiring a read access + BitmapReadAccess* pReadAcc = rBmp.AcquireReadAccess(); + + // TODO(P2): Acquiring a read access can actually + // force a read from VRAM, thus, avoiding this + // step somehow will increase performance + // here. + if( pReadAcc ) + { + // try again: now, WinSalBitmap must have + // generated a DIB + if( rBmp.GetSystemData( aBmpSysData ) && + aBmpSysData.pDIB ) + { + return drawDIBits( rGraphics, + aBmpSysData.pDIB ); + } + + rBmp.ReleaseAccess( pReadAcc ); + } + } + else + { + return drawDIBits( rGraphics, + aBmpSysData.pDIB ); + } + + // failed to generate DIBits from vcl bitmap + return false; + } + + /** Create a chunk of raw RGBA data GDI+ Bitmap from VCL BbitmapEX + */ + RawRGBABitmap bitmapFromVCLBitmapEx( const ::BitmapEx& rBmpEx ) + { + // TODO(P2): Avoid temporary bitmap generation, maybe + // even ensure that created DIBs are copied back to + // BmpEx (currently, every AcquireReadAccess() will + // make the local bitmap copy unique, effectively + // duplicating the memory used) + + ENSURE_AND_THROW( rBmpEx.IsTransparent(), + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "BmpEx not transparent" ); + + // convert transparent bitmap to 32bit RGBA + // ======================================== + + const ::Size aBmpSize( rBmpEx.GetSizePixel() ); + + RawRGBABitmap aBmpData; + aBmpData.mnWidth = aBmpSize.Width(); + aBmpData.mnHeight = aBmpSize.Height(); + aBmpData.mpBitmapData.reset( new sal_uInt8[ 4*aBmpData.mnWidth*aBmpData.mnHeight ] ); + + Bitmap aBitmap( rBmpEx.GetBitmap() ); + + ScopedBitmapReadAccess pReadAccess( aBitmap.AcquireReadAccess(), + aBitmap ); + + const sal_Int32 nWidth( aBmpSize.Width() ); + const sal_Int32 nHeight( aBmpSize.Height() ); + + ENSURE_AND_THROW( pReadAccess.get() != NULL, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unable to acquire read acces to bitmap" ); + + if( rBmpEx.IsAlpha() ) + { + Bitmap aAlpha( rBmpEx.GetAlpha().GetBitmap() ); + + ScopedBitmapReadAccess pAlphaReadAccess( aAlpha.AcquireReadAccess(), + aAlpha ); + + // By convention, the access buffer always has + // one of the following formats: + // + // BMP_FORMAT_1BIT_MSB_PAL + // BMP_FORMAT_4BIT_MSN_PAL + // BMP_FORMAT_8BIT_PAL + // BMP_FORMAT_16BIT_TC_LSB_MASK + // BMP_FORMAT_24BIT_TC_BGR + // BMP_FORMAT_32BIT_TC_MASK + // + // and is always BMP_FORMAT_BOTTOM_UP + // + // This is the way + // WinSalBitmap::AcquireBuffer() sets up the + // buffer + + ENSURE_AND_THROW( pAlphaReadAccess.get() != NULL, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unable to acquire read acces to alpha" ); + + ENSURE_AND_THROW( pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL || + pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unsupported alpha scanline format" ); + + BitmapColor aCol; + const sal_Int32 nWidth( aBmpSize.Width() ); + const sal_Int32 nHeight( aBmpSize.Height() ); + sal_uInt8* pCurrOutput( aBmpData.mpBitmapData.get() ); + int x, y; + + for( y=0; y<nHeight; ++y ) + { + switch( pReadAccess->GetScanlineFormat() ) + { + case BMP_FORMAT_8BIT_PAL: + { + Scanline pScan = pReadAccess->GetScanline( y ); + Scanline pAScan = pAlphaReadAccess->GetScanline( y ); + + for( x=0; x<nWidth; ++x ) + { + aCol = pReadAccess->GetPaletteColor( *pScan++ ); + + *pCurrOutput++ = aCol.GetBlue(); + *pCurrOutput++ = aCol.GetGreen(); + *pCurrOutput++ = aCol.GetRed(); + + // out notion of alpha is + // different from the rest + // of the world's + *pCurrOutput++ = 255 - (BYTE)*pAScan++; + } + } + break; + + case BMP_FORMAT_24BIT_TC_BGR: + { + Scanline pScan = pReadAccess->GetScanline( y ); + Scanline pAScan = pAlphaReadAccess->GetScanline( y ); + + for( x=0; x<nWidth; ++x ) + { + // store as RGBA + *pCurrOutput++ = *pScan++; + *pCurrOutput++ = *pScan++; + *pCurrOutput++ = *pScan++; + + // out notion of alpha is + // different from the rest + // of the world's + *pCurrOutput++ = 255 - (BYTE)*pAScan++; + } + } + break; + + // TODO(P2): Might be advantageous + // to hand-formulate the following + // formats, too. + case BMP_FORMAT_1BIT_MSB_PAL: + // FALLTHROUGH intended + case BMP_FORMAT_4BIT_MSN_PAL: + // FALLTHROUGH intended + case BMP_FORMAT_16BIT_TC_LSB_MASK: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_MASK: + { + Scanline pAScan = pAlphaReadAccess->GetScanline( y ); + + // using fallback for those + // seldom formats + for( x=0; x<nWidth; ++x ) + { + // yes. x and y are swapped on Get/SetPixel + aCol = pReadAccess->GetColor(y,x); + + *pCurrOutput++ = aCol.GetBlue(); + *pCurrOutput++ = aCol.GetGreen(); + *pCurrOutput++ = aCol.GetRed(); + + // out notion of alpha is + // different from the rest + // of the world's + *pCurrOutput++ = 255 - (BYTE)*pAScan++; + } + } + break; + + case BMP_FORMAT_1BIT_LSB_PAL: + // FALLTHROUGH intended + case BMP_FORMAT_4BIT_LSN_PAL: + // FALLTHROUGH intended + case BMP_FORMAT_8BIT_TC_MASK: + // FALLTHROUGH intended + case BMP_FORMAT_24BIT_TC_RGB: + // FALLTHROUGH intended + case BMP_FORMAT_24BIT_TC_MASK: + // FALLTHROUGH intended + case BMP_FORMAT_16BIT_TC_MSB_MASK: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_ABGR: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_ARGB: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_BGRA: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_RGBA: + // FALLTHROUGH intended + default: + ENSURE_AND_THROW( false, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unexpected scanline format - has " + "WinSalBitmap::AcquireBuffer() changed?" ); + } + } + } + else + { + Bitmap aMask( rBmpEx.GetMask() ); + + ScopedBitmapReadAccess pMaskReadAccess( aMask.AcquireReadAccess(), + aMask ); + + // By convention, the access buffer always has + // one of the following formats: + // + // BMP_FORMAT_1BIT_MSB_PAL + // BMP_FORMAT_4BIT_MSN_PAL + // BMP_FORMAT_8BIT_PAL + // BMP_FORMAT_16BIT_TC_LSB_MASK + // BMP_FORMAT_24BIT_TC_BGR + // BMP_FORMAT_32BIT_TC_MASK + // + // and is always BMP_FORMAT_BOTTOM_UP + // + // This is the way + // WinSalBitmap::AcquireBuffer() sets up the + // buffer + + ENSURE_AND_THROW( pMaskReadAccess.get() != NULL, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unable to acquire read acces to mask" ); + + ENSURE_AND_THROW( pMaskReadAccess->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unsupported mask scanline format" ); + + BitmapColor aCol; + int nCurrBit; + const int nMask( 1L ); + const int nInitialBit(7); + sal_uInt8* pCurrOutput( aBmpData.mpBitmapData.get() ); + int x, y; + + // mapping table, to get from mask index color to + // alpha value (which depends on the mask's palette) + sal_uInt8 aColorMap[2]; + + const BitmapColor& rCol0( pMaskReadAccess->GetPaletteColor( 0 ) ); + const BitmapColor& rCol1( pMaskReadAccess->GetPaletteColor( 1 ) ); + + // shortcut for true luminance calculation + // (assumes that palette is grey-level). Note the + // swapped the indices here, to account for the + // fact that VCL's notion of alpha is inverted to + // the rest of the world's. + aColorMap[0] = rCol1.GetRed(); + aColorMap[1] = rCol0.GetRed(); + + for( y=0; y<nHeight; ++y ) + { + switch( pReadAccess->GetScanlineFormat() ) + { + case BMP_FORMAT_8BIT_PAL: + { + Scanline pScan = pReadAccess->GetScanline( y ); + Scanline pMScan = pMaskReadAccess->GetScanline( y ); + + for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x ) + { + aCol = pReadAccess->GetPaletteColor( *pScan++ ); + + *pCurrOutput++ = aCol.GetBlue(); + *pCurrOutput++ = aCol.GetGreen(); + *pCurrOutput++ = aCol.GetRed(); + + *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ]; + nCurrBit = ((nCurrBit - 1) % 8L) & 7L; + } + } + break; + + case BMP_FORMAT_24BIT_TC_BGR: + { + Scanline pScan = pReadAccess->GetScanline( y ); + Scanline pMScan = pMaskReadAccess->GetScanline( y ); + + for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x ) + { + // store as RGBA + *pCurrOutput++ = *pScan++; + *pCurrOutput++ = *pScan++; + *pCurrOutput++ = *pScan++; + + *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ]; + nCurrBit = ((nCurrBit - 1) % 8L) & 7L; + } + } + break; + + // TODO(P2): Might be advantageous + // to hand-formulate the following + // formats, too. + case BMP_FORMAT_1BIT_MSB_PAL: + // FALLTHROUGH intended + case BMP_FORMAT_4BIT_MSN_PAL: + // FALLTHROUGH intended + case BMP_FORMAT_16BIT_TC_LSB_MASK: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_MASK: + { + Scanline pMScan = pMaskReadAccess->GetScanline( y ); + + // using fallback for those + // seldom formats + for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x ) + { + // yes. x and y are swapped on Get/SetPixel + aCol = pReadAccess->GetColor(y,x); + + // store as RGBA + *pCurrOutput++ = aCol.GetBlue(); + *pCurrOutput++ = aCol.GetGreen(); + *pCurrOutput++ = aCol.GetRed(); + + *pCurrOutput++ = aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ]; + nCurrBit = ((nCurrBit - 1) % 8L) & 7L; + } + } + break; + + case BMP_FORMAT_1BIT_LSB_PAL: + // FALLTHROUGH intended + case BMP_FORMAT_4BIT_LSN_PAL: + // FALLTHROUGH intended + case BMP_FORMAT_8BIT_TC_MASK: + // FALLTHROUGH intended + case BMP_FORMAT_24BIT_TC_RGB: + // FALLTHROUGH intended + case BMP_FORMAT_24BIT_TC_MASK: + // FALLTHROUGH intended + case BMP_FORMAT_16BIT_TC_MSB_MASK: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_ABGR: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_ARGB: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_BGRA: + // FALLTHROUGH intended + case BMP_FORMAT_32BIT_TC_RGBA: + // FALLTHROUGH intended + default: + ENSURE_AND_THROW( false, + "::dxcanvas::tools::bitmapFromVCLBitmapEx(): " + "Unexpected scanline format - has " + "WinSalBitmap::AcquireBuffer() changed?" ); + } + } + } + + return aBmpData; + } + + bool drawVCLBitmapEx( const ::boost::shared_ptr< SurfaceGraphics >& rGraphics, + const ::BitmapEx& rBmpEx ) + { + if( !rBmpEx.IsTransparent() ) + { + Bitmap aBmp( rBmpEx.GetBitmap() ); + return drawVCLBitmap( rGraphics, aBmp ); + } + else + { + return drawRGBABits( rGraphics, + bitmapFromVCLBitmapEx( rBmpEx ) ); + } + } + + bool bitmapExFromUnoTunnel( BitmapEx& o_rBmpEx, + const uno::Reference< lang::XUnoTunnel >& xTunnel ) + { + if( !xTunnel.is() ) + return false; + + sal_Int64 nPtr = xTunnel->getSomething( vcl::unotools::getTunnelIdentifier( vcl::unotools::Id_BitmapEx ) ); + if( !nPtr ) + return false; + + o_rBmpEx = *(BitmapEx*)nPtr; + + return true; + } + } + + bool drawVCLBitmapFromUnoTunnel( const ::boost::shared_ptr< SurfaceGraphics >& rGraphics, + const uno::Reference< lang::XUnoTunnel >& xTunnel ) + { + BitmapEx aBmpEx; + + if( !bitmapExFromUnoTunnel( aBmpEx, + xTunnel ) ) + return false; + + return drawVCLBitmapEx( rGraphics, aBmpEx ); + } + + util::TriState isAlphaVCLBitmapFromUnoTunnel( const uno::Reference< lang::XUnoTunnel >& xTunnel ) + { + if( !xTunnel.is() ) + return util::TriState_INDETERMINATE; + + sal_Int64 nPtr = xTunnel->getSomething( vcl::unotools::getTunnelIdentifier( vcl::unotools::Id_BitmapEx ) ); + if( !nPtr ) + return util::TriState_INDETERMINATE; + + BitmapEx& rBmpEx( *(BitmapEx*)nPtr ); + + return rBmpEx.IsTransparent() ? + util::TriState_YES : util::TriState_NO; + } + } +} diff --git a/canvas/source/directx/dx_vcltools.hxx b/canvas/source/directx/dx_vcltools.hxx new file mode 100755 index 000000000000..5458d00eeae2 --- /dev/null +++ b/canvas/source/directx/dx_vcltools.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dx_vcltools.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-11-01 18:00:10 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _DXCANVAS_VCLTOOLS_HXX +#define _DXCANVAS_VCLTOOLS_HXX + +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif +#ifndef _COM_SUN_STAR_UTIL_TRISTATE_HPP_ +#include <com/sun/star/util/TriState.hpp> +#endif + +#include <boost/shared_ptr.hpp> + + +namespace com { namespace sun { namespace star { namespace lang +{ + class XUnoTunnel; +} } } } + + +namespace dxcanvas +{ + class SurfaceGraphics; + + namespace tools + { + /** Raw RGBA bitmap data, + contiguous in memory + */ + struct RawRGBABitmap + { + sal_Int32 mnWidth; + sal_Int32 mnHeight; + ::boost::shared_ptr< sal_uInt8 > mpBitmapData; + }; + + bool drawVCLBitmapFromUnoTunnel( const ::boost::shared_ptr< SurfaceGraphics >& rGraphics, + const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XUnoTunnel >& xTunnel ); + + ::com::sun::star::util::TriState isAlphaVCLBitmapFromUnoTunnel( const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XUnoTunnel >& xTunnel ); + } +} + +#endif /* _DXCANVAS_VCLTOOLS_HXX */ |