[Libreoffice-commits] core.git: 3 commits - basegfx/Library_basegfx.mk basegfx/source canvas/Library_oglcanvas.mk canvas/Module_canvas.mk canvas/source configure.ac cppcanvas/source include/basegfx include/cppcanvas include/sal offapi/com officecfg/registry Repository.mk sdext/source sd/source slideshow/source
Thorsten Behrens
tbehrens at suse.com
Mon Oct 7 08:34:18 PDT 2013
Repository.mk | 1
basegfx/Library_basegfx.mk | 1
basegfx/source/polygon/b2dpolypolygontools.cxx | 133 +
basegfx/source/tools/numbertools.cxx | 61
canvas/Library_oglcanvas.mk | 69
canvas/Module_canvas.mk | 6
canvas/source/cairo/cairo_canvashelper.hxx | 1
canvas/source/directx/dx_bitmapcanvashelper.hxx | 1
canvas/source/directx/dx_canvashelper.hxx | 2
canvas/source/opengl/ogl_bitmapcanvashelper.cxx | 101 +
canvas/source/opengl/ogl_bitmapcanvashelper.hxx | 103 +
canvas/source/opengl/ogl_buffercontext.hxx | 34
canvas/source/opengl/ogl_canvasbitmap.cxx | 55
canvas/source/opengl/ogl_canvasbitmap.hxx | 78
canvas/source/opengl/ogl_canvascustomsprite.cxx | 261 +++
canvas/source/opengl/ogl_canvascustomsprite.hxx | 100 +
canvas/source/opengl/ogl_canvasfont.cxx | 81
canvas/source/opengl/ogl_canvasfont.hxx | 68
canvas/source/opengl/ogl_canvashelper.cxx | 1011 ++++++++++++
canvas/source/opengl/ogl_canvashelper.hxx | 238 ++
canvas/source/opengl/ogl_canvastools.cxx | 139 +
canvas/source/opengl/ogl_canvastools.hxx | 38
canvas/source/opengl/ogl_spritecanvas.cxx | 195 ++
canvas/source/opengl/ogl_spritecanvas.hxx | 118 +
canvas/source/opengl/ogl_spritedevicehelper.cxx | 1249 +++++++++++++++
canvas/source/opengl/ogl_spritedevicehelper.hxx | 179 ++
canvas/source/opengl/ogl_textlayout.cxx | 215 ++
canvas/source/opengl/ogl_textlayout.hxx | 79
canvas/source/opengl/ogl_texturecache.cxx | 124 +
canvas/source/opengl/ogl_texturecache.hxx | 64
canvas/source/opengl/ogl_tools.hxx | 31
canvas/source/opengl/oglcanvas.component | 16
canvas/source/tools/canvastools.cxx | 10
canvas/source/vcl/canvashelper.hxx | 1
configure.ac | 2
cppcanvas/source/wrapper/implspritecanvas.cxx | 4
cppcanvas/source/wrapper/implspritecanvas.hxx | 4
include/basegfx/polygon/b2dpolypolygontools.hxx | 20
include/basegfx/tools/tools.hxx | 25
include/cppcanvas/spritecanvas.hxx | 4
include/sal/log-areas.dox | 2
offapi/com/sun/star/rendering/XSpriteCanvas.idl | 11
officecfg/registry/data/org/openoffice/Office/Canvas.xcu | 1
sd/source/ui/presenter/PresenterCanvas.cxx | 11
sd/source/ui/presenter/PresenterCanvas.hxx | 4
sd/source/ui/presenter/PresenterTextView.cxx | 1
sd/source/ui/presenter/SlideRenderer.cxx | 1
sdext/source/presenter/PresenterSlideSorter.cxx | 1
slideshow/source/engine/slideview.cxx | 9
slideshow/source/engine/transitions/slidechangebase.cxx | 1
slideshow/source/engine/waitsymbol.cxx | 13
51 files changed, 4933 insertions(+), 44 deletions(-)
New commits:
commit e52f1bd7b34fc73f52aadf1d33efa6685a0b22e8
Author: Thorsten Behrens <tbehrens at suse.com>
Date: Tue Jan 31 01:07:48 2012 +0100
Add opengl canvas implementation.
Adds opengl canvas implementation - display-list-based, all
rendering done as textured geometry. Needs shader support.
Currently compiles and works on Linux, Mac should be ~easy to
add, win32 eventually.
Change-Id: Ibf3eb88d6a36a91b2960a3a6320d708160e4fc14
diff --git a/Repository.mk b/Repository.mk
index 7e393d4..d306442 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -229,6 +229,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,ooo, \
$(if $(filter unx,$(GUIBASE)),desktop_detector) \
$(if $(DISABLE_SCRIPTING),,dlgprov) \
$(if $(ENABLE_DIRECTX),directx9canvas) \
+ $(if $(ENABLE_OPENGL),oglcanvas) \
drawinglayer \
editeng \
egi \
diff --git a/canvas/Library_oglcanvas.mk b/canvas/Library_oglcanvas.mk
new file mode 100644
index 0000000..fca6996
--- /dev/null
+++ b/canvas/Library_oglcanvas.mk
@@ -0,0 +1,69 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,oglcanvas))
+
+$(eval $(call gb_Library_set_componentfile,oglcanvas,canvas/source/opengl/oglcanvas))
+
+$(eval $(call gb_Library_use_sdk_api,oglcanvas))
+
+$(eval $(call gb_Library_use_libraries,oglcanvas,\
+ sal \
+ cppu \
+ basegfx \
+ cppuhelper \
+ comphelper \
+ vcl \
+ tk \
+ tl \
+ i18nlangtag \
+ canvastools \
+ $(gb_UWINAPI) \
+))
+
+$(eval $(call gb_Library_add_exception_objects,oglcanvas,\
+ canvas/source/opengl/ogl_bitmapcanvashelper \
+ canvas/source/opengl/ogl_canvasbitmap \
+ canvas/source/opengl/ogl_canvascustomsprite \
+ canvas/source/opengl/ogl_canvasfont \
+ canvas/source/opengl/ogl_canvashelper \
+ canvas/source/opengl/ogl_canvastools \
+ canvas/source/opengl/ogl_spritecanvas \
+ canvas/source/opengl/ogl_spritedevicehelper \
+ canvas/source/opengl/ogl_textlayout \
+ canvas/source/opengl/ogl_texturecache \
+))
+
+$(eval $(call gb_Library_use_externals,oglcanvas,\
+ boost_headers \
+))
+
+ifeq ($(strip $(OS)),MACOSX)
+$(eval $(call gb_Library_use_system_darwin_frameworks,oglcanvas,\
+ Cocoa \
+ GLUT \
+ OpenGL \
+))
+
+else ifeq ($(strip $(OS)),WNT)
+$(eval $(call gb_Library_use_system_win32_libs,oglcanvas,\
+ gdi32 \
+ glu32 \
+ opengl32 \
+))
+
+else
+$(eval $(call gb_Library_add_libs,oglcanvas,\
+ -lGL \
+ -lGLU \
+ -lX11 \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/canvas/Module_canvas.mk b/canvas/Module_canvas.mk
index 0bc364e..510cb98 100644
--- a/canvas/Module_canvas.mk
+++ b/canvas/Module_canvas.mk
@@ -32,6 +32,12 @@ $(eval $(call gb_Module_add_targets,canvas,\
))
endif
+ifeq ($(ENABLE_OPENGL),TRUE)
+$(eval $(call gb_Module_add_targets,canvas,\
+ Library_oglcanvas \
+))
+endif
+
ifneq ($(ENABLE_DIRECTX),)
$(eval $(call gb_Module_add_targets,canvas,\
Library_directx9canvas \
diff --git a/canvas/source/opengl/ogl_bitmapcanvashelper.cxx b/canvas/source/opengl/ogl_bitmapcanvashelper.cxx
new file mode 100644
index 0000000..1d132cb
--- /dev/null
+++ b/canvas/source/opengl/ogl_bitmapcanvashelper.cxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "ogl_bitmapcanvashelper.hxx"
+
+#include <canvas/debug.hxx>
+#include <canvas/canvastools.hxx>
+#include <tools/diagnose_ex.h>
+
+
+using namespace ::com::sun::star;
+
+namespace oglcanvas
+{
+ BitmapCanvasHelper::BitmapCanvasHelper()
+ {}
+
+ void BitmapCanvasHelper::disposing()
+ {
+ CanvasHelper::disposing();
+ }
+
+ void BitmapCanvasHelper::init( rendering::XGraphicDevice& rDevice,
+ SpriteDeviceHelper& rDeviceHelper,
+ const geometry::IntegerSize2D& rSize )
+ {
+ maSize = rSize;
+ CanvasHelper::init(rDevice,rDeviceHelper);
+ }
+
+ void BitmapCanvasHelper::copyRect( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XBitmapCanvas >& /*sourceCanvas*/,
+ const geometry::RealRectangle2D& /*sourceRect*/,
+ const rendering::ViewState& /*sourceViewState*/,
+ const rendering::RenderState& /*sourceRenderState*/,
+ const geometry::RealRectangle2D& /*destRect*/,
+ const rendering::ViewState& /*destViewState*/,
+ const rendering::RenderState& /*destRenderState*/ )
+ {
+ // TODO(F2): copyRect NYI
+ }
+
+ geometry::IntegerSize2D BitmapCanvasHelper::getSize()
+ {
+ return maSize;
+ }
+
+ uno::Reference< rendering::XBitmap > BitmapCanvasHelper::getScaledBitmap( const geometry::RealSize2D& /*newSize*/,
+ sal_Bool /*beFast*/ )
+ {
+ // TODO(F1):
+ return uno::Reference< rendering::XBitmap >();
+ }
+
+ uno::Sequence< sal_Int8 > BitmapCanvasHelper::getData( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
+ const geometry::IntegerRectangle2D& /*rect*/ )
+ {
+ // TODO(F2): NYI - and improbable to ever be
+ return uno::Sequence< sal_Int8 >();
+ }
+
+ void BitmapCanvasHelper::setData( const uno::Sequence< sal_Int8 >& /*data*/,
+ const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
+ const geometry::IntegerRectangle2D& /*rect*/ )
+ {
+ // TODO(F2): NYI - and improbable to ever be
+ }
+
+ void BitmapCanvasHelper::setPixel( const uno::Sequence< sal_Int8 >& /*color*/,
+ const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
+ const geometry::IntegerPoint2D& /*pos*/ )
+ {
+ // TODO(F2): NYI - and improbable to ever be
+ }
+
+ uno::Sequence< sal_Int8 > BitmapCanvasHelper::getPixel( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
+ const geometry::IntegerPoint2D& /*pos*/ )
+ {
+ // TODO(F2): NYI - and improbable to ever be
+ return uno::Sequence< sal_Int8 >();
+ }
+
+ rendering::IntegerBitmapLayout BitmapCanvasHelper::getMemoryLayout()
+ {
+ return ::canvas::tools::getStdMemoryLayout(getSize());
+ }
+
+ bool BitmapCanvasHelper::hasAlpha() const
+ {
+ return true;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_bitmapcanvashelper.hxx b/canvas/source/opengl/ogl_bitmapcanvashelper.hxx
new file mode 100644
index 0000000..50781c3
--- /dev/null
+++ b/canvas/source/opengl/ogl_bitmapcanvashelper.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef OGL_BITMAPCANVASHELPER_HXX_
+#define OGL_BITMAPCANVASHELPER_HXX_
+
+#include <com/sun/star/rendering/XBitmapCanvas.hpp>
+#include <com/sun/star/rendering/XIntegerBitmap.hpp>
+
+#include <basegfx/vector/b2isize.hxx>
+#include <basegfx/vector/b2dsize.hxx>
+
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+#include "ogl_canvashelper.hxx"
+
+
+namespace oglcanvas
+{
+ /** Helper class for basic canvas functionality. */
+ class BitmapCanvasHelper : public CanvasHelper
+ {
+ public:
+ BitmapCanvasHelper();
+
+ /// Release all references
+ void disposing();
+
+ /** Initialize canvas helper
+
+ This method late-initializes the canvas helper, providing
+ it with the necessary device and output objects. Note that
+ the CanvasHelper does <em>not</em> take ownership of the
+ passed rDevice reference, nor does it perform any
+ reference counting. Thus, to prevent the reference counted
+ SpriteCanvas object from deletion, the user of this class
+ is responsible for holding ref-counted references itself!
+
+ @param rDevice
+ Reference device this canvas is associated with
+
+ */
+ void init( ::com::sun::star::rendering::XGraphicDevice& rDevice,
+ SpriteDeviceHelper& rDeviceHelper,
+ const ::com::sun::star::geometry::IntegerSize2D& rSize );
+
+ // BitmapCanvasHelper functionality
+ // ================================
+
+ void copyRect( const ::com::sun::star::rendering::XCanvas* rCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XBitmapCanvas >& sourceCanvas,
+ const ::com::sun::star::geometry::RealRectangle2D& sourceRect,
+ const ::com::sun::star::rendering::ViewState& sourceViewState,
+ const ::com::sun::star::rendering::RenderState& sourceRenderState,
+ const ::com::sun::star::geometry::RealRectangle2D& destRect,
+ const ::com::sun::star::rendering::ViewState& destViewState,
+ const ::com::sun::star::rendering::RenderState& destRenderState );
+
+ ::com::sun::star::geometry::IntegerSize2D getSize();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > queryBitmapCanvas();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmap >
+ getScaledBitmap( const ::com::sun::star::geometry::RealSize2D& newSize,
+ sal_Bool beFast );
+
+ ::com::sun::star::uno::Sequence< sal_Int8 >
+ getData( ::com::sun::star::rendering::IntegerBitmapLayout& bitmapLayout,
+ const ::com::sun::star::geometry::IntegerRectangle2D& rect );
+
+ void setData( const ::com::sun::star::uno::Sequence< sal_Int8 >& data,
+ const ::com::sun::star::rendering::IntegerBitmapLayout& bitmapLayout,
+ const ::com::sun::star::geometry::IntegerRectangle2D& rect );
+
+ void setPixel( const ::com::sun::star::uno::Sequence< sal_Int8 >& color,
+ const ::com::sun::star::rendering::IntegerBitmapLayout& bitmapLayout,
+ const ::com::sun::star::geometry::IntegerPoint2D& pos );
+
+ ::com::sun::star::uno::Sequence< sal_Int8 >
+ getPixel( ::com::sun::star::rendering::IntegerBitmapLayout& bitmapLayout,
+ const ::com::sun::star::geometry::IntegerPoint2D& pos );
+
+ ::com::sun::star::rendering::IntegerBitmapLayout getMemoryLayout();
+
+ bool hasAlpha() const;
+
+ private:
+ ::com::sun::star::geometry::IntegerSize2D maSize;
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_buffercontext.hxx b/canvas/source/opengl/ogl_buffercontext.hxx
new file mode 100644
index 0000000..b996412
--- /dev/null
+++ b/canvas/source/opengl/ogl_buffercontext.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef OGL_BUFFERCONTEXT_HXX_
+#define OGL_BUFFERCONTEXT_HXX_
+
+#include <sal/config.h>
+#include <boost/shared_ptr.hpp>
+
+namespace oglcanvas
+{
+ struct IBufferContext
+ {
+ virtual ~IBufferContext() {}
+
+ /// start render to buffer. changes gl current context
+ virtual bool startBufferRendering() = 0;
+
+ /// end render to buffer. switches to window context, and selects rendered texture
+ virtual bool endBufferRendering() = 0;
+ };
+
+ typedef ::boost::shared_ptr<IBufferContext> IBufferContextSharedPtr;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_canvasbitmap.cxx b/canvas/source/opengl/ogl_canvasbitmap.cxx
new file mode 100644
index 0000000..d78baf5
--- /dev/null
+++ b/canvas/source/opengl/ogl_canvasbitmap.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "ogl_canvasbitmap.hxx"
+
+#include <canvas/debug.hxx>
+#include <canvas/canvastools.hxx>
+#include <tools/diagnose_ex.h>
+
+
+using namespace ::com::sun::star;
+
+namespace oglcanvas
+{
+ CanvasBitmap::CanvasBitmap( const geometry::IntegerSize2D& rSize,
+ const SpriteCanvasRef& rDevice,
+ SpriteDeviceHelper& rDeviceHelper,
+ bool bHasAlpha ) :
+ mpDevice( rDevice ),
+ mbHasAlpha( bHasAlpha )
+ {
+ ENSURE_OR_THROW( mpDevice.is(),
+ "CanvasBitmap::CanvasBitmap(): Invalid surface or device" );
+
+ maCanvasHelper.init( *mpDevice.get(), rDeviceHelper, rSize );
+ }
+
+ CanvasBitmap::CanvasBitmap( const CanvasBitmap& rSrc ) :
+ mpDevice( rSrc.mpDevice ),
+ mbHasAlpha( rSrc.mbHasAlpha )
+ {
+ maCanvasHelper = rSrc.maCanvasHelper;
+ }
+
+ void SAL_CALL CanvasBitmap::disposeThis()
+ {
+ mpDevice.clear();
+
+ // forward to parent
+ CanvasBitmapBaseT::disposeThis();
+ }
+
+ bool CanvasBitmap::renderRecordedActions() const
+ {
+ return maCanvasHelper.renderRecordedActions();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_canvasbitmap.hxx b/canvas/source/opengl/ogl_canvasbitmap.hxx
new file mode 100644
index 0000000..b874bde
--- /dev/null
+++ b/canvas/source/opengl/ogl_canvasbitmap.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef OGL_CANVASBITMAP_HXX
+#define OGL_CANVASBITMAP_HXX
+
+#include <cppuhelper/compbase2.hxx>
+
+#include <com/sun/star/rendering/XBitmapCanvas.hpp>
+#include <com/sun/star/rendering/XIntegerBitmap.hpp>
+
+#include <canvas/base/integerbitmapbase.hxx>
+#include <canvas/base/disambiguationhelper.hxx>
+#include <basegfx/vector/b2isize.hxx>
+
+#include <boost/shared_ptr.hpp>
+
+#include "ogl_bitmapcanvashelper.hxx"
+#include "ogl_spritecanvas.hxx"
+
+
+/* Definition of CanvasBitmap class */
+
+namespace oglcanvas
+{
+ typedef ::cppu::WeakComponentImplHelper2< ::com::sun::star::rendering::XBitmapCanvas,
+ ::com::sun::star::rendering::XIntegerBitmap > CanvasBitmapBase_Base;
+ typedef ::canvas::IntegerBitmapBase<
+ ::canvas::DisambiguationHelper< CanvasBitmapBase_Base >,
+ BitmapCanvasHelper,
+ ::osl::MutexGuard,
+ ::cppu::OWeakObject > CanvasBitmapBaseT;
+
+ class CanvasBitmap : public CanvasBitmapBaseT
+ {
+ public:
+ /** Create a canvas bitmap for the given surface
+
+ @param rSize
+ Size of the bitmap
+
+ @param rDevice
+ Reference device, with which bitmap should be compatible
+ */
+ CanvasBitmap( const ::com::sun::star::geometry::IntegerSize2D& rSize,
+ const SpriteCanvasRef& rDevice,
+ SpriteDeviceHelper& rDeviceHelper,
+ bool bHasAlpha );
+
+ /** Create verbatim copy (including all recorded actions)
+ */
+ CanvasBitmap( const CanvasBitmap& rSrc );
+
+ /// Dispose all internal references
+ virtual void disposeThis();
+
+ /** Write out recorded actions
+ */
+ bool renderRecordedActions() const;
+
+ private:
+ /** MUST hold here, too, since CanvasHelper only contains a
+ raw pointer (without refcounting)
+ */
+ SpriteCanvasRef mpDevice;
+ bool mbHasAlpha;
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_canvascustomsprite.cxx b/canvas/source/opengl/ogl_canvascustomsprite.cxx
new file mode 100644
index 0000000..7c08671
--- /dev/null
+++ b/canvas/source/opengl/ogl_canvascustomsprite.cxx
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "ogl_canvascustomsprite.hxx"
+#include "ogl_canvastools.hxx"
+#include "ogl_tools.hxx"
+
+#include <canvas/debug.hxx>
+#include <canvas/verbosetrace.hxx>
+#include <canvas/verifyinput.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <canvas/canvastools.hxx>
+
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
+#include <basegfx/polygon/b2dpolygontriangulator.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <GL/glext.h>
+
+
+using namespace ::com::sun::star;
+
+namespace oglcanvas
+{
+ CanvasCustomSprite::CanvasCustomSprite( const ::com::sun::star::geometry::RealSize2D& rSpriteSize,
+ const SpriteCanvasRef& rRefDevice,
+ SpriteDeviceHelper& rDeviceHelper ) :
+ mpSpriteCanvas( rRefDevice ),
+ maSize(rSpriteSize),
+ mxClip(),
+ maTransformation(),
+ maPosition(),
+ mfAlpha(0.0),
+ mfPriority(0.0)
+ {
+ ENSURE_OR_THROW( rRefDevice.get(),
+ "CanvasCustomSprite::CanvasCustomSprite(): Invalid sprite canvas" );
+
+ ::canvas::tools::setIdentityAffineMatrix2D(maTransformation);
+ maCanvasHelper.init( *rRefDevice.get(),
+ rDeviceHelper );
+ }
+
+ void SAL_CALL CanvasCustomSprite::disposeThis()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ mpSpriteCanvas.clear();
+
+ // forward to parent
+ CanvasCustomSpriteBaseT::disposeThis();
+ }
+
+ void SAL_CALL CanvasCustomSprite::setAlpha( double alpha ) throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+ {
+ canvas::tools::verifyRange( alpha, 0.0, 1.0 );
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ mfAlpha = alpha;
+ }
+
+ void SAL_CALL CanvasCustomSprite::move( const geometry::RealPoint2D& aNewPos,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState ) throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+ {
+ canvas::tools::verifyArgs(aNewPos, viewState, renderState,
+ BOOST_CURRENT_FUNCTION,
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ ::basegfx::B2DHomMatrix aTransform;
+ ::canvas::tools::mergeViewAndRenderTransform(aTransform,
+ viewState,
+ renderState);
+
+ // convert position to device pixel
+ maPosition = ::basegfx::unotools::b2DPointFromRealPoint2D(aNewPos);
+ maPosition *= aTransform;
+ }
+
+ void SAL_CALL CanvasCustomSprite::transform( const geometry::AffineMatrix2D& aTransformation ) throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ maTransformation = aTransformation;
+ }
+
+ void SAL_CALL CanvasCustomSprite::clip( const uno::Reference< rendering::XPolyPolygon2D >& xClip ) throw (uno::RuntimeException)
+ {
+ mxClip = xClip;
+ }
+
+ void SAL_CALL CanvasCustomSprite::setPriority( double nPriority ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ mfPriority = nPriority;
+ }
+
+ void SAL_CALL CanvasCustomSprite::show() throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( mpSpriteCanvas.is() )
+ mpSpriteCanvas->show(this);
+ }
+
+ void SAL_CALL CanvasCustomSprite::hide() throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if( mpSpriteCanvas.is() )
+ mpSpriteCanvas->hide(this);
+ }
+
+ uno::Reference< rendering::XCanvas > SAL_CALL CanvasCustomSprite::getContentCanvas() throw (uno::RuntimeException)
+ {
+ return this;
+ }
+
+ bool CanvasCustomSprite::renderSprite() const
+ {
+ if( ::basegfx::fTools::equalZero( mfAlpha ) )
+ return true;
+
+ TransformationPreserver aPreserver1;
+ const ::basegfx::B2IVector aSpriteSizePixel(
+ ::canvas::tools::roundUp( maSize.Width ),
+ ::canvas::tools::roundUp( maSize.Height ));
+
+ // translate sprite to output position
+ glTranslated(maPosition.getX(), maPosition.getY(), 0);
+
+ {
+ TransformationPreserver aPreserver2;
+
+ // apply sprite content transformation matrix
+ double aGLTransform[] =
+ {
+ maTransformation.m00, maTransformation.m10, 0, 0,
+ maTransformation.m01, maTransformation.m11, 0, 0,
+ 0, 0, 1, 0,
+ maTransformation.m02, maTransformation.m12, 0, 1
+ };
+ glMultMatrixd(aGLTransform);
+
+ IBufferContextSharedPtr pBufferContext;
+ if( mfAlpha != 1.0 || mxClip.is() )
+ {
+ // drats. need to render to temp surface before, and then
+ // composite that to screen
+
+ // TODO(P3): buffer pbuffer, maybe even keep content
+ // (in a texture?)
+ pBufferContext=maCanvasHelper.getDeviceHelper()->createBufferContext(aSpriteSizePixel);
+ pBufferContext->startBufferRendering();
+ }
+
+ // this ends up in pBufferContext, if that one's "current"
+ if( !maCanvasHelper.renderRecordedActions() )
+ return false;
+
+ if( pBufferContext )
+ {
+ // content ended up in background buffer - compose to
+ // screen now. Calls below switches us back to window
+ // context, and binds to generated, dynamic texture
+ pBufferContext->endBufferRendering();
+
+ glEnable(GL_TEXTURE_2D);
+ glTexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MAG_FILTER,
+ GL_NEAREST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,
+ GL_ONE_MINUS_SRC_ALPHA);
+
+ // blend against fixed vertex color; texture alpha is multiplied in
+ glColor4f(1,1,1,mfAlpha);
+
+ if( mxClip.is() )
+ {
+ const double fWidth=maSize.Width;
+ const double fHeight=maSize.Height;
+
+ // TODO(P3): buffer triangulation
+ const ::basegfx::B2DPolygon& rTriangulatedPolygon(
+ ::basegfx::triangulator::triangulate(
+ ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(mxClip)));
+
+ basegfx::B2DPolygon rTriangleList(
+ basegfx::tools::clipTriangleListOnRange(
+ rTriangulatedPolygon,
+ basegfx::B2DRange(
+ 0,0,
+ aSpriteSizePixel.getX(),
+ aSpriteSizePixel.getY())));
+
+ glBegin(GL_TRIANGLES);
+ for( sal_uInt32 i=0; i<rTriangulatedPolygon.count(); i++ )
+ {
+ const ::basegfx::B2DPoint& rPt( rTriangulatedPolygon.getB2DPoint(i) );
+ const double s(rPt.getX()/fWidth);
+ const double t(rPt.getY()/fHeight);
+ glTexCoord2f(s,t); glVertex2d(rPt.getX(), rPt.getY());
+ }
+ glEnd();
+ }
+ else
+ {
+ const double fWidth=maSize.Width/aSpriteSizePixel.getX();
+ const double fHeight=maSize.Height/aSpriteSizePixel.getY();
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2f(0,0); glVertex2d(0,0);
+ glTexCoord2f(0,fHeight); glVertex2d(0, aSpriteSizePixel.getY());
+ glTexCoord2f(fWidth,0); glVertex2d(aSpriteSizePixel.getX(),0);
+ glTexCoord2f(fWidth,fHeight); glVertex2d(aSpriteSizePixel.getX(),aSpriteSizePixel.getY());
+ glEnd();
+ }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+ }
+ }
+
+ glColor4f(1,0,0,1);
+ glBegin(GL_LINE_STRIP);
+ glVertex2d(-2,-2);
+ glVertex2d(-2,maSize.Height+4);
+ glVertex2d(maSize.Width+4,maSize.Height+4);
+ glVertex2d(maSize.Width+4,-2);
+ glVertex2d(-2,-2);
+ glVertex2d(maSize.Width+4,maSize.Height+4);
+ glEnd();
+
+ std::vector<double> aVec;
+ aVec.push_back(mfAlpha);
+ aVec.push_back(mfPriority);
+ aVec.push_back(maCanvasHelper.getRecordedActionCount());
+ renderOSD( aVec, 10 );
+
+ return true;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_canvascustomsprite.hxx b/canvas/source/opengl/ogl_canvascustomsprite.hxx
new file mode 100644
index 0000000..a96ce64
--- /dev/null
+++ b/canvas/source/opengl/ogl_canvascustomsprite.hxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef OGL_CANVASCUSTOMSPRITE_HXX
+#define OGL_CANVASCUSTOMSPRITE_HXX
+
+#include <cppuhelper/compbase2.hxx>
+#include <comphelper/uno3.hxx>
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/rendering/XCustomSprite.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2isize.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+#include <canvas/base/disambiguationhelper.hxx>
+
+#include "ogl_spritecanvas.hxx"
+#include "ogl_canvashelper.hxx"
+
+
+namespace oglcanvas
+{
+ typedef ::cppu::WeakComponentImplHelper2< ::com::sun::star::rendering::XCustomSprite,
+ ::com::sun::star::rendering::XCanvas > CanvasCustomSpriteBase_Base;
+ typedef ::canvas::CanvasBase<
+ ::canvas::DisambiguationHelper< CanvasCustomSpriteBase_Base >,
+ CanvasHelper,
+ ::osl::MutexGuard,
+ ::cppu::OWeakObject > CanvasCustomSpriteBaseT;
+
+ /* Definition of CanvasCustomSprite class */
+
+ class CanvasCustomSprite : public CanvasCustomSpriteBaseT
+ {
+ public:
+ /** Create a custom sprite
+
+ @param rSpriteSize
+ Size of the sprite in pixel
+
+ @param rRefDevice
+ Associated output device
+
+ @param rSpriteCanvas
+ Target canvas
+
+ @param rDevice
+ Target DX device
+ */
+ CanvasCustomSprite( const ::com::sun::star::geometry::RealSize2D& rSpriteSize,
+ const SpriteCanvasRef& rRefDevice,
+ SpriteDeviceHelper& rDeviceHelper );
+
+ virtual void disposeThis();
+
+ // XSprite
+ virtual void SAL_CALL setAlpha( double alpha ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL move( const ::com::sun::star::geometry::RealPoint2D& aNewPos, const ::com::sun::star::rendering::ViewState& viewState, const ::com::sun::star::rendering::RenderState& renderState ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL transform( const ::com::sun::star::geometry::AffineMatrix2D& aTransformation ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL clip( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >& aClip ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPriority( double nPriority ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL show() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL hide() throw (::com::sun::star::uno::RuntimeException);
+
+ // XCustomSprite
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > SAL_CALL getContentCanvas() throw (::com::sun::star::uno::RuntimeException);
+
+ double getPriority() const { return mfPriority; }
+
+ /// Render sprite content at sprite position
+ bool renderSprite() const;
+
+ private:
+ /** MUST hold here, too, since CanvasHelper only contains a
+ raw pointer (without refcounting)
+ */
+ SpriteCanvasRef mpSpriteCanvas;
+ const ::com::sun::star::geometry::RealSize2D maSize;
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D > mxClip;
+ ::com::sun::star::geometry::AffineMatrix2D maTransformation;
+ ::basegfx::B2DPoint maPosition;
+ double mfAlpha;
+ double mfPriority;
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_canvasfont.cxx b/canvas/source/opengl/ogl_canvasfont.cxx
new file mode 100644
index 0000000..d465919
--- /dev/null
+++ b/canvas/source/opengl/ogl_canvasfont.cxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "ogl_canvasfont.hxx"
+#include "ogl_textlayout.hxx"
+
+#include <com/sun/star/rendering/XSpriteCanvas.hpp>
+#include <com/sun/star/rendering/PanoseWeight.hpp>
+
+
+using namespace ::com::sun::star;
+
+namespace oglcanvas
+{
+ CanvasFont::CanvasFont( const rendering::FontRequest& rFontRequest,
+ const uno::Sequence< beans::PropertyValue >& /*extraFontProperties*/,
+ const geometry::Matrix2D& fontMatrix ) :
+ CanvasFontBaseT( m_aMutex ),
+ maFontRequest( rFontRequest ),
+ maFontMatrix( fontMatrix )
+ {
+ }
+
+ void SAL_CALL CanvasFont::disposing()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ }
+
+ uno::Reference< rendering::XTextLayout > SAL_CALL CanvasFont::createTextLayout( const rendering::StringContext& aText,
+ sal_Int8 nDirection,
+ sal_Int64 nRandomSeed ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ return new TextLayout( aText, nDirection, nRandomSeed, ImplRef( this ) );
+ }
+
+ uno::Sequence< double > SAL_CALL CanvasFont::getAvailableSizes( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // TODO
+ return uno::Sequence< double >();
+ }
+
+ uno::Sequence< beans::PropertyValue > SAL_CALL CanvasFont::getExtraFontProperties( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // TODO
+ return uno::Sequence< beans::PropertyValue >();
+ }
+
+ rendering::FontRequest SAL_CALL CanvasFont::getFontRequest( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ return maFontRequest;
+ }
+
+ rendering::FontMetrics SAL_CALL CanvasFont::getFontMetrics( ) throw (uno::RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // TODO
+ return rendering::FontMetrics();
+ }
+
+ const ::com::sun::star::geometry::Matrix2D& CanvasFont::getFontMatrix() const
+ {
+ return maFontMatrix;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_canvasfont.hxx b/canvas/source/opengl/ogl_canvasfont.hxx
new file mode 100644
index 0000000..9a26297
--- /dev/null
+++ b/canvas/source/opengl/ogl_canvasfont.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef OGL_CANVASFONT_HXX
+#define OGL_CANVASFONT_HXX
+
+#include <comphelper/implementationreference.hxx>
+
+#include <cppuhelper/compbase1.hxx>
+#include <comphelper/broadcasthelper.hxx>
+
+#include <com/sun/star/rendering/XCanvas.hpp>
+#include <com/sun/star/rendering/XCanvasFont.hpp>
+
+#include <rtl/ref.hxx>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+
+
+/* Definition of CanvasFont class */
+
+namespace oglcanvas
+{
+ class SpriteCanvas;
+
+ typedef ::cppu::WeakComponentImplHelper1< ::com::sun::star::rendering::XCanvasFont > CanvasFontBaseT;
+
+ class CanvasFont : public ::comphelper::OBaseMutex,
+ public CanvasFontBaseT,
+ private ::boost::noncopyable
+ {
+ public:
+ typedef ::comphelper::ImplementationReference<
+ CanvasFont,
+ ::com::sun::star::rendering::XCanvasFont > ImplRef;
+
+ CanvasFont( const ::com::sun::star::rendering::FontRequest& fontRequest,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& extraFontProperties,
+ const ::com::sun::star::geometry::Matrix2D& fontMatrix );
+
+ /// Dispose all internal references
+ virtual void SAL_CALL disposing();
+
+ // XCanvasFont
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XTextLayout > SAL_CALL createTextLayout( const ::com::sun::star::rendering::StringContext& aText, sal_Int8 nDirection, sal_Int64 nRandomSeed ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::rendering::FontRequest SAL_CALL getFontRequest( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::rendering::FontMetrics SAL_CALL getFontMetrics( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< double > SAL_CALL getAvailableSizes( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getExtraFontProperties( ) throw (::com::sun::star::uno::RuntimeException);
+
+ const ::com::sun::star::geometry::Matrix2D& getFontMatrix() const;
+
+ private:
+ ::com::sun::star::rendering::FontRequest maFontRequest;
+ ::com::sun::star::geometry::Matrix2D maFontMatrix;
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_canvashelper.cxx b/canvas/source/opengl/ogl_canvashelper.cxx
new file mode 100644
index 0000000..ae349b9
--- /dev/null
+++ b/canvas/source/opengl/ogl_canvashelper.cxx
@@ -0,0 +1,1011 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#define GL_GLEXT_PROTOTYPES
+
+#include "ogl_canvashelper.hxx"
+
+#include <rtl/crc.h>
+#include <canvas/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <basegfx/tools/canvastools.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolygontriangulator.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+
+#include <com/sun/star/rendering/TexturingMode.hpp>
+#include <com/sun/star/rendering/CompositeOperation.hpp>
+#include <com/sun/star/rendering/RepaintResult.hpp>
+#include <com/sun/star/rendering/PathCapType.hpp>
+#include <com/sun/star/rendering/PathJoinType.hpp>
+
+#include <vcl/virdev.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/font.hxx>
+
+#include "ogl_canvasfont.hxx"
+#include "ogl_canvastools.hxx"
+#include "ogl_canvasbitmap.hxx"
+#include "ogl_spritecanvas.hxx"
+#include "ogl_texturecache.hxx"
+#include "ogl_tools.hxx"
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <GL/glext.h>
+
+#include <boost/scoped_array.hpp>
+
+
+using namespace ::com::sun::star;
+
+namespace oglcanvas
+{
+ /* Concepts:
+ =========
+
+ This OpenGL canvas implementation tries to keep all render
+ output as high-level as possible, i.e. geometry data and
+ externally-provided bitmaps. Therefore, calls at the
+ XCanvas-interfaces are not immediately transformed into colored
+ pixel inside some GL buffer, but are retained simply with their
+ call parameters. Only after XSpriteCanvas::updateScreen() has
+ been called, this all gets transferred to the OpenGL subsystem
+ and converted to a visible scene. The big advantage is, this
+ makes sprite modifications practically zero-overhead, and saves
+ a lot on texture memory (compared to the directx canvas, which
+ immediately dumps every render call into a texture).
+
+ The drawback, of course, is that complex images churn a lot of
+ GPU cycles on every re-rendering.
+
+ For the while, I'll be using immediate mode, i.e. transfer data
+ over and over again to the OpenGL subsystem. Alternatively,
+ there are display lists, which at least keep the data on the
+ server, or even better, vertex buffers, which copy geometry
+ data over en bloc.
+
+ Next todo: put polygon geometry into vertex buffer (LRU cache
+ necessary?) - or, rather, buffer objects! prune entries older
+ than one updateScreen() call)
+
+ Text: http://www.opengl.org/resources/features/fontsurvey/
+ */
+
+ struct CanvasHelper::Action
+ {
+ ::basegfx::B2DHomMatrix maTransform;
+ GLenum meSrcBlendMode;
+ GLenum meDstBlendMode;
+ rendering::ARGBColor maARGBColor;
+ ::basegfx::B2DPolyPolygonVector maPolyPolys;
+
+ ::boost::function6< bool,
+ const CanvasHelper&,
+ const ::basegfx::B2DHomMatrix&,
+ GLenum,
+ GLenum,
+ const rendering::ARGBColor&,
+ const ::basegfx::B2DPolyPolygonVector& > maFunction;
+ };
+
+ namespace
+ {
+ bool lcl_drawPoint( const CanvasHelper& /*rHelper*/,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
+ GLenum eDstBlend,
+ const rendering::ARGBColor& rColor,
+ const geometry::RealPoint2D& rPoint )
+ {
+ TransformationPreserver aPreserver;
+ setupState(rTransform, eSrcBlend, eDstBlend, rColor);
+
+ glBegin(GL_POINTS);
+ glVertex2d(rPoint.X, rPoint.Y);
+ glEnd();
+
+ return true;
+ }
+
+ bool lcl_drawLine( const CanvasHelper& /*rHelper*/,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
+ GLenum eDstBlend,
+ const rendering::ARGBColor& rColor,
+ const geometry::RealPoint2D& rStartPoint,
+ const geometry::RealPoint2D& rEndPoint )
+ {
+ TransformationPreserver aPreserver;
+ setupState(rTransform, eSrcBlend, eDstBlend, rColor);
+
+ glBegin(GL_LINES);
+ glVertex2d(rStartPoint.X, rStartPoint.Y);
+ glVertex2d(rEndPoint.X, rEndPoint.Y);
+ glEnd();
+
+ return true;
+ }
+
+ bool lcl_drawPolyPolygon( const CanvasHelper& /*rHelper*/,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
+ GLenum eDstBlend,
+ const rendering::ARGBColor& rColor,
+ const ::basegfx::B2DPolyPolygonVector& rPolyPolygons )
+ {
+ TransformationPreserver aPreserver;
+ setupState(rTransform, eSrcBlend, eDstBlend, rColor);
+
+ ::basegfx::B2DPolyPolygonVector::const_iterator aCurr=rPolyPolygons.begin();
+ const ::basegfx::B2DPolyPolygonVector::const_iterator aEnd=rPolyPolygons.end();
+ while( aCurr != aEnd )
+ renderPolyPolygon(*aCurr++);
+
+ return true;
+ }
+
+ bool lcl_fillPolyPolygon( const CanvasHelper& /*rHelper*/,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
+ GLenum eDstBlend,
+ const rendering::ARGBColor& rColor,
+ const ::basegfx::B2DPolyPolygonVector& rPolyPolygons )
+ {
+ TransformationPreserver aPreserver;
+ setupState(rTransform, eSrcBlend, eDstBlend, rColor);
+
+ ::basegfx::B2DPolyPolygonVector::const_iterator aCurr=rPolyPolygons.begin();
+ const ::basegfx::B2DPolyPolygonVector::const_iterator aEnd=rPolyPolygons.end();
+ while( aCurr != aEnd )
+ {
+ glBegin(GL_TRIANGLES);
+ renderComplexPolyPolygon(*aCurr++);
+ glEnd();
+ }
+
+ return true;
+ }
+
+ bool lcl_fillGradientPolyPolygon( const CanvasHelper& rHelper,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
+ GLenum eDstBlend,
+ const ::canvas::ParametricPolyPolygon::Values& rValues,
+ const rendering::Texture& rTexture,
+ const ::basegfx::B2DPolyPolygonVector& rPolyPolygons )
+ {
+ TransformationPreserver aPreserver;
+ setupState(rTransform, eSrcBlend, eDstBlend, rendering::ARGBColor());
+
+ // convert to weird canvas textur coordinate system (not
+ // [0,1]^2, but path coordinate system)
+ ::basegfx::B2DHomMatrix aTextureTransform;
+ ::basegfx::unotools::homMatrixFromAffineMatrix( aTextureTransform,
+ rTexture.AffineTransform );
+ ::basegfx::B2DRange aBounds;
+ ::basegfx::B2DPolyPolygonVector::const_iterator aCurr=rPolyPolygons.begin();
+ const ::basegfx::B2DPolyPolygonVector::const_iterator aEnd=rPolyPolygons.end();
+ while( aCurr != aEnd )
+ aBounds.expand(::basegfx::tools::getRange(*aCurr++));
+ aTextureTransform.translate(-aBounds.getMinX(), -aBounds.getMinY());
+ aTextureTransform.scale(1/aBounds.getWidth(), 1/aBounds.getHeight());
+
+ const sal_Int32 nNumCols=rValues.maColors.getLength();
+ uno::Sequence< rendering::ARGBColor > aColors(nNumCols);
+ rendering::ARGBColor* const pColors=aColors.getArray();
+ rendering::ARGBColor* pCurrCol=pColors;
+ for( sal_Int32 i=0; i<nNumCols; ++i )
+ *pCurrCol++ = rHelper.getDevice()->getDeviceColorSpace()->convertToARGB(rValues.maColors[i])[0];
+
+ OSL_ASSERT(nNumCols == rValues.maStops.getLength());
+
+ switch( rValues.meType )
+ {
+ case ::canvas::ParametricPolyPolygon::GRADIENT_LINEAR:
+ rHelper.getDeviceHelper()->useLinearGradientShader(pColors,
+ rValues.maStops,
+ aTextureTransform);
+ break;
+
+ case ::canvas::ParametricPolyPolygon::GRADIENT_ELLIPTICAL:
+ rHelper.getDeviceHelper()->useRadialGradientShader(pColors,
+ rValues.maStops,
+ aTextureTransform);
+ break;
+
+ case ::canvas::ParametricPolyPolygon::GRADIENT_RECTANGULAR:
+ rHelper.getDeviceHelper()->useRectangularGradientShader(pColors,
+ rValues.maStops,
+ aTextureTransform);
+ break;
+
+ default:
+ ENSURE_OR_THROW( false,
+ "CanvasHelper lcl_fillGradientPolyPolygon(): Unexpected case" );
+ }
+
+
+ aCurr=rPolyPolygons.begin();
+ while( aCurr != aEnd )
+ {
+ glBegin(GL_TRIANGLES);
+ renderComplexPolyPolygon(*aCurr++);
+ glEnd();
+ }
+
+ glUseProgram(0);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+
+ return true;
+ }
+
+ bool lcl_drawOwnBitmap( const CanvasHelper& /*rHelper*/,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
+ GLenum eDstBlend,
+ const rendering::ARGBColor& rColor,
+ const CanvasBitmap& rBitmap )
+ {
+ TransformationPreserver aPreserver;
+ setupState(rTransform, eSrcBlend, eDstBlend, rColor);
+
+ return rBitmap.renderRecordedActions();
+ }
+
+ bool lcl_drawGenericBitmap( const CanvasHelper& rHelper,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
+ GLenum eDstBlend,
+ const rendering::ARGBColor& rColor,
+ const geometry::IntegerSize2D& rPixelSize,
+ const uno::Sequence<sal_Int8>& rPixelData,
+ sal_uInt32 nPixelCrc32 )
+ {
+ TransformationPreserver aPreserver;
+ setupState(rTransform, eSrcBlend, eDstBlend, rColor);
+
+ const unsigned int nTexId=rHelper.getDeviceHelper()->getTextureCache().getTexture(
+ rPixelSize, rPixelData.getConstArray(), nPixelCrc32);
+
+ glBindTexture(GL_TEXTURE_2D, nTexId);
+ glEnable(GL_TEXTURE_2D);
+ glTexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MAG_FILTER,
+ GL_NEAREST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,
+ GL_ONE_MINUS_SRC_ALPHA);
+
+ // blend against fixed vertex color; texture alpha is multiplied in
+ glColor4f(1,1,1,1);
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2f(0,0); glVertex2d(0,0);
+ glTexCoord2f(0,1); glVertex2d(0, rPixelSize.Height);
+ glTexCoord2f(1,0); glVertex2d(rPixelSize.Width,0);
+ glTexCoord2f(1,1); glVertex2d(rPixelSize.Width,rPixelSize.Height);
+ glEnd();
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+
+ return true;
+ }
+
+ bool lcl_fillTexturedPolyPolygon( const CanvasHelper& rHelper,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
+ GLenum eDstBlend,
+ const rendering::Texture& rTexture,
+ const geometry::IntegerSize2D& rPixelSize,
+ const uno::Sequence<sal_Int8>& rPixelData,
+ sal_uInt32 nPixelCrc32,
+ const ::basegfx::B2DPolyPolygonVector& rPolyPolygons )
+ {
+ TransformationPreserver aPreserver;
+ setupState(rTransform, eSrcBlend, eDstBlend, rendering::ARGBColor());
+
+ const unsigned int nTexId=rHelper.getDeviceHelper()->getTextureCache().getTexture(
+ rPixelSize, rPixelData.getConstArray(), nPixelCrc32);
+
+ glBindTexture(GL_TEXTURE_2D, nTexId);
+ glEnable(GL_TEXTURE_2D);
+ glTexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_MAG_FILTER,
+ GL_NEAREST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,
+ GL_ONE_MINUS_SRC_ALPHA);
+
+ // convert to weird canvas textur coordinate system (not
+ // [0,1]^2, but path coordinate system)
+ ::basegfx::B2DHomMatrix aTextureTransform;
+ ::basegfx::unotools::homMatrixFromAffineMatrix( aTextureTransform,
+ rTexture.AffineTransform );
+ ::basegfx::B2DRange aBounds;
+ ::basegfx::B2DPolyPolygonVector::const_iterator aCurr=rPolyPolygons.begin();
+ const ::basegfx::B2DPolyPolygonVector::const_iterator aEnd=rPolyPolygons.end();
+ while( aCurr != aEnd )
+ aBounds.expand(::basegfx::tools::getRange(*aCurr++));
+ aTextureTransform.translate(-aBounds.getMinX(), -aBounds.getMinY());
+ aTextureTransform.scale(1/aBounds.getWidth(), 1/aBounds.getHeight());
+ aTextureTransform.invert();
+
+ glMatrixMode(GL_TEXTURE);
+ double aTexTransform[] =
+ {
+ aTextureTransform.get(0,0), aTextureTransform.get(1,0), 0, 0,
+ aTextureTransform.get(0,1), aTextureTransform.get(1,1), 0, 0,
+ 0, 0, 1, 0,
+ aTextureTransform.get(0,2), aTextureTransform.get(1,2), 0, 1
+ };
+ glLoadMatrixd(aTexTransform);
+
+ // blend against fixed vertex color; texture alpha is multiplied in
+ glColor4f(1,1,1,rTexture.Alpha);
+
+ aCurr=rPolyPolygons.begin();
+ while( aCurr != aEnd )
+ {
+ glBegin(GL_TRIANGLES);
+ renderComplexPolyPolygon(*aCurr++);
+ glEnd();
+ }
+
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+
+ return true;
+ }
+ }
+
+ CanvasHelper::CanvasHelper() :
+ mpDevice( NULL ),
+ mpRecordedActions()
+ {}
+
+ CanvasHelper::~CanvasHelper()
+ {}
+
+ CanvasHelper& CanvasHelper::operator=( const CanvasHelper& rSrc )
+ {
+ mpDevice = rSrc.mpDevice;
+ mpDeviceHelper = rSrc.mpDeviceHelper;
+ mpRecordedActions = rSrc.mpRecordedActions;
+ return *this;
+ }
+
+ void CanvasHelper::disposing()
+ {
+ RecordVectorT aThrowaway;
+ mpRecordedActions.swap( aThrowaway );
+ mpDevice = NULL;
+ mpDeviceHelper = NULL;
+ }
+
+ void CanvasHelper::init( rendering::XGraphicDevice& rDevice,
+ SpriteDeviceHelper& rDeviceHelper )
+ {
+ mpDevice = &rDevice;
+ mpDeviceHelper = &rDeviceHelper;
+ }
+
+ void CanvasHelper::clear()
+ {
+ mpRecordedActions->clear();
+ }
+
+ void CanvasHelper::drawPoint( const rendering::XCanvas* /*pCanvas*/,
+ const geometry::RealPoint2D& aPoint,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ if( mpDevice )
+ {
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+ rAct.maFunction = ::boost::bind(&lcl_drawPoint,
+ _1,_2,_3,_4,_5,
+ aPoint);
+ }
+ }
+
+ void CanvasHelper::drawLine( const rendering::XCanvas* /*pCanvas*/,
+ const geometry::RealPoint2D& aStartPoint,
+ const geometry::RealPoint2D& aEndPoint,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ if( mpDevice )
+ {
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+ rAct.maFunction = ::boost::bind(&lcl_drawLine,
+ _1,_2,_3,_4,_5,
+ aStartPoint,aEndPoint);
+ }
+ }
+
+ void CanvasHelper::drawBezier( const rendering::XCanvas* /*pCanvas*/,
+ const geometry::RealBezierSegment2D& aBezierSegment,
+ const geometry::RealPoint2D& aEndPoint,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ if( mpDevice )
+ {
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+
+ // TODO(F2): subdivide&render whole curve
+ rAct.maFunction = ::boost::bind(&lcl_drawLine,
+ _1,_2,_3,_4,_5,
+ geometry::RealPoint2D(
+ aBezierSegment.Px,
+ aBezierSegment.Py),
+ aEndPoint);
+ }
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawPolyPolygon( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ ENSURE_OR_THROW( xPolyPolygon.is(),
+ "CanvasHelper::drawPolyPolygon: polygon is NULL");
+
+ if( mpDevice )
+ {
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+ rAct.maPolyPolys.push_back(
+ ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon));
+ rAct.maPolyPolys.back().makeUnique(); // own copy, for thread safety
+
+ rAct.maFunction = &lcl_drawPolyPolygon;
+ }
+
+ // TODO(P1): Provide caching here.
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::strokePolyPolygon( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState,
+ const rendering::StrokeAttributes& /*strokeAttributes*/ )
+ {
+ ENSURE_OR_THROW( xPolyPolygon.is(),
+ "CanvasHelper::strokePolyPolygon: polygon is NULL");
+
+ if( mpDevice )
+ {
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+ rAct.maPolyPolys.push_back(
+ ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon));
+ rAct.maPolyPolys.back().makeUnique(); // own copy, for thread safety
+
+ // TODO(F3): fallback to drawPolyPolygon currently
+ rAct.maFunction = &lcl_drawPolyPolygon;
+ }
+
+ // TODO(P1): Provide caching here.
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::strokeTexturedPolyPolygon( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XPolyPolygon2D >& /*xPolyPolygon*/,
+ const rendering::ViewState& /*viewState*/,
+ const rendering::RenderState& /*renderState*/,
+ const uno::Sequence< rendering::Texture >& /*textures*/,
+ const rendering::StrokeAttributes& /*strokeAttributes*/ )
+ {
+ // TODO
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::strokeTextureMappedPolyPolygon( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XPolyPolygon2D >& /*xPolyPolygon*/,
+ const rendering::ViewState& /*viewState*/,
+ const rendering::RenderState& /*renderState*/,
+ const uno::Sequence< rendering::Texture >& /*textures*/,
+ const uno::Reference< geometry::XMapping2D >& /*xMapping*/,
+ const rendering::StrokeAttributes& /*strokeAttributes*/ )
+ {
+ // TODO
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XPolyPolygon2D > CanvasHelper::queryStrokeShapes( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XPolyPolygon2D >& /*xPolyPolygon*/,
+ const rendering::ViewState& /*viewState*/,
+ const rendering::RenderState& /*renderState*/,
+ const rendering::StrokeAttributes& /*strokeAttributes*/ )
+ {
+ // TODO
+ return uno::Reference< rendering::XPolyPolygon2D >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::fillPolyPolygon( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ ENSURE_OR_THROW( xPolyPolygon.is(),
+ "CanvasHelper::fillPolyPolygon: polygon is NULL");
+
+ if( mpDevice )
+ {
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+ rAct.maPolyPolys.push_back(
+ ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon));
+ rAct.maPolyPolys.back().makeUnique(); // own copy, for thread safety
+
+ rAct.maFunction = &lcl_fillPolyPolygon;
+ }
+
+ // TODO(P1): Provide caching here.
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::fillTexturedPolyPolygon( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState,
+ const uno::Sequence< rendering::Texture >& textures )
+ {
+ ENSURE_OR_THROW( xPolyPolygon.is(),
+ "CanvasHelper::fillPolyPolygon: polygon is NULL");
+
+ if( mpDevice )
+ {
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+ rAct.maPolyPolys.push_back(
+ ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon));
+ rAct.maPolyPolys.back().makeUnique(); // own copy, for thread safety
+
+ // TODO(F1): Multi-texturing
+ if( textures[0].Gradient.is() )
+ {
+ // try to cast XParametricPolyPolygon2D reference to
+ // our implementation class.
+ ::canvas::ParametricPolyPolygon* pGradient =
+ dynamic_cast< ::canvas::ParametricPolyPolygon* >( textures[0].Gradient.get() );
+
+ if( pGradient )
+ {
+ // copy state from Gradient polypoly locally
+ // (given object might change!)
+ const ::canvas::ParametricPolyPolygon::Values& rValues(
+ pGradient->getValues() );
+
+ rAct.maFunction = ::boost::bind(&lcl_fillGradientPolyPolygon,
+ _1,_2,_3,_4,
+ rValues,
+ textures[0],
+ _6);
+ }
+ else
+ {
+ // TODO(F1): The generic case is missing here
+ ENSURE_OR_THROW( false,
+ "CanvasHelper::fillTexturedPolyPolygon(): unknown parametric polygon encountered" );
+ }
+ }
+ else if( textures[0].Bitmap.is() )
+ {
+ // own bitmap?
+ CanvasBitmap* pOwnBitmap=dynamic_cast<CanvasBitmap*>(textures[0].Bitmap.get());
+ if( pOwnBitmap )
+ {
+ // TODO(F2): own texture bitmap
+ }
+ else
+ {
+ // TODO(P3): Highly inefficient - simply copies pixel data
+
+ uno::Reference< rendering::XIntegerReadOnlyBitmap > xIntegerBitmap(
+ textures[0].Bitmap,
+ uno::UNO_QUERY);
+ if( xIntegerBitmap.is() )
+ {
+ const geometry::IntegerSize2D aSize=xIntegerBitmap->getSize();
+ rendering::IntegerBitmapLayout aLayout;
+ uno::Sequence<sal_Int8> aPixelData=
+ xIntegerBitmap->getData(
+ aLayout,
+ geometry::IntegerRectangle2D(0,0,aSize.Width,aSize.Height));
+
+ // force-convert color to ARGB8888 int color space
+ uno::Sequence<sal_Int8> aARGBBytes(
+ aLayout.ColorSpace->convertToIntegerColorSpace(
+ aPixelData,
+ canvas::tools::getStdColorSpace()));
+
+ rAct.maFunction = ::boost::bind(&lcl_fillTexturedPolyPolygon,
+ _1,_2,_3,_4,
+ textures[0],
+ aSize,
+ aARGBBytes,
+ rtl_crc32(0,
+ aARGBBytes.getConstArray(),
+ aARGBBytes.getLength()),
+ _6);
+ }
+ // TODO(F1): handle non-integer case
+ }
+ }
+ }
+
+ // TODO(P1): Provide caching here.
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::fillTextureMappedPolyPolygon( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XPolyPolygon2D >& /*xPolyPolygon*/,
+ const rendering::ViewState& /*viewState*/,
+ const rendering::RenderState& /*renderState*/,
+ const uno::Sequence< rendering::Texture >& /*textures*/,
+ const uno::Reference< geometry::XMapping2D >& /*xMapping*/ )
+ {
+ // TODO
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCanvasFont > CanvasHelper::createFont( const rendering::XCanvas* /*pCanvas*/,
+ const rendering::FontRequest& fontRequest,
+ const uno::Sequence< beans::PropertyValue >& extraFontProperties,
+ const geometry::Matrix2D& fontMatrix )
+ {
+ if( mpDevice )
+ return uno::Reference< rendering::XCanvasFont >(
+ new CanvasFont(fontRequest, extraFontProperties, fontMatrix ) );
+
+ return uno::Reference< rendering::XCanvasFont >();
+ }
+
+ uno::Sequence< rendering::FontInfo > CanvasHelper::queryAvailableFonts( const rendering::XCanvas* /*pCanvas*/,
+ const rendering::FontInfo& /*aFilter*/,
+ const uno::Sequence< beans::PropertyValue >& /*aFontProperties*/ )
+ {
+ // TODO
+ return uno::Sequence< rendering::FontInfo >();
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawText( const rendering::XCanvas* /*pCanvas*/,
+ const rendering::StringContext& /*text*/,
+ const uno::Reference< rendering::XCanvasFont >& /*xFont*/,
+ const rendering::ViewState& /*viewState*/,
+ const rendering::RenderState& /*renderState*/,
+ sal_Int8 /*textDirection*/ )
+ {
+ // TODO - but not used from slideshow
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawTextLayout( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XTextLayout >& xLayoutetText,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ ENSURE_OR_THROW( xLayoutetText.is(),
+ "CanvasHelper::drawTextLayout: text is NULL");
+
+ if( mpDevice )
+ {
+ VirtualDevice aVDev;
+ aVDev.EnableOutput(false);
+
+ CanvasFont* pFont=dynamic_cast<CanvasFont*>(xLayoutetText->getFont().get());
+ const rendering::StringContext& rTxt=xLayoutetText->getText();
+ if( pFont && rTxt.Length )
+ {
+ // create the font
+ const rendering::FontRequest& rFontRequest = pFont->getFontRequest();
+ const geometry::Matrix2D& rFontMatrix = pFont->getFontMatrix();
+ ::Font aFont(
+ rFontRequest.FontDescription.FamilyName,
+ rFontRequest.FontDescription.StyleName,
+ Size( 0, ::basegfx::fround(rFontRequest.CellSize)));
+
+ aFont.SetAlign( ALIGN_BASELINE );
+ aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE );
+ aFont.SetVertical( (rFontRequest.FontDescription.IsVertical==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 = aVDev.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
+ aVDev.SetFont(aFont);
+
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+
+ // handle custom spacing, if there
+ uno::Sequence<double> aLogicalAdvancements=xLayoutetText->queryLogicalAdvancements();
+ if( aLogicalAdvancements.getLength() )
+ {
+ // create the DXArray
+ const sal_Int32 nLen( aLogicalAdvancements.getLength() );
+ ::boost::scoped_array<sal_Int32> pDXArray( new sal_Int32[nLen] );
+ for( sal_Int32 i=0; i<nLen; ++i )
+ pDXArray[i] = basegfx::fround( aLogicalAdvancements[i] );
+
+ // get the glyphs
+ aVDev.GetTextOutlines(rAct.maPolyPolys,
+ rTxt.Text,
+ 0,
+ (xub_StrLen)rTxt.StartPosition,
+ (xub_StrLen)rTxt.Length,
+ true,
+ 0,
+ pDXArray.get() );
+ }
+ else
+ {
+ // get the glyphs
+ aVDev.GetTextOutlines(rAct.maPolyPolys,
+ rTxt.Text,
+ 0,
+ (xub_StrLen)rTxt.StartPosition,
+ (xub_StrLen)rTxt.Length );
+ }
+
+ // own copy, for thread safety
+ std::for_each(rAct.maPolyPolys.begin(),
+ rAct.maPolyPolys.end(),
+ ::boost::mem_fn(&::basegfx::B2DPolyPolygon::makeUnique));
+
+ rAct.maFunction = &lcl_fillPolyPolygon;
+ }
+ }
+
+ // TODO
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawBitmap( const rendering::XCanvas* /*pCanvas*/,
+ const uno::Reference< rendering::XBitmap >& xBitmap,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ ENSURE_OR_THROW( xBitmap.is(),
+ "CanvasHelper::drawBitmap: bitmap is NULL");
+
+ if( mpDevice )
+ {
+ // own bitmap?
+ CanvasBitmap* pOwnBitmap=dynamic_cast<CanvasBitmap*>(xBitmap.get());
+ if( pOwnBitmap )
+ {
+ // insert as transformed copy of bitmap action vector -
+ // during rendering, this gets rendered into a temporary
+ // buffer, and then composited to the front
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+ rAct.maFunction = ::boost::bind(&lcl_drawOwnBitmap,
+ _1,_2,_3,_4,_5,
+ *pOwnBitmap);
+ }
+ else
+ {
+ // TODO(P3): Highly inefficient - simply copies pixel data
+
+ uno::Reference< rendering::XIntegerReadOnlyBitmap > xIntegerBitmap(
+ xBitmap, uno::UNO_QUERY);
+ if( xIntegerBitmap.is() )
+ {
+ const geometry::IntegerSize2D aSize=xBitmap->getSize();
+ rendering::IntegerBitmapLayout aLayout;
+ uno::Sequence<sal_Int8> aPixelData=
+ xIntegerBitmap->getData(
+ aLayout,
+ geometry::IntegerRectangle2D(0,0,aSize.Width,aSize.Height));
+
+ // force-convert color to ARGB8888 int color space
+ uno::Sequence<sal_Int8> aARGBBytes(
+ aLayout.ColorSpace->convertToIntegerColorSpace(
+ aPixelData,
+ canvas::tools::getStdColorSpace()));
+
+ mpRecordedActions->push_back( Action() );
+ Action& rAct=mpRecordedActions->back();
+
+ setupGraphicsState( rAct, viewState, renderState );
+ rAct.maFunction = ::boost::bind(&lcl_drawGenericBitmap,
+ _1,_2,_3,_4,_5,
+ aSize, aARGBBytes,
+ rtl_crc32(0,
+ aARGBBytes.getConstArray(),
+ aARGBBytes.getLength()));
+ }
+ // TODO(F1): handle non-integer case
+ }
+ }
+
+ // TODO(P1): Provide caching here.
+ return uno::Reference< rendering::XCachedPrimitive >(NULL);
+ }
+
+ uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawBitmapModulated( const rendering::XCanvas* pCanvas,
+ const uno::Reference< rendering::XBitmap >& xBitmap,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ // TODO(F3): remove this wart altogether
+ return drawBitmap(pCanvas, xBitmap, viewState, renderState);
+ }
+
+ uno::Reference< rendering::XGraphicDevice > CanvasHelper::getDevice()
+ {
+ return uno::Reference< rendering::XGraphicDevice >(mpDevice);
+ }
+
+ void CanvasHelper::setupGraphicsState( Action& o_action,
+ const rendering::ViewState& viewState,
+ const rendering::RenderState& renderState )
+ {
+ ENSURE_OR_THROW( mpDevice,
+ "CanvasHelper::setupGraphicsState: reference device invalid" );
+
+ // TODO(F3): clipping
+ // TODO(P2): think about caching transformations between canvas calls
+
+ // setup overall transform only now. View clip above was
+ // relative to view transform
+ ::basegfx::B2DHomMatrix aTransform;
+ ::canvas::tools::mergeViewAndRenderTransform(o_action.maTransform,
+ viewState,
+ renderState);
+ // setup compositing - mapping courtesy David Reveman
+ // (glitz_operator.c)
+ switch( renderState.CompositeOperation )
+ {
+ case rendering::CompositeOperation::OVER:
+ o_action.meSrcBlendMode=GL_ONE;
+ o_action.meDstBlendMode=GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case rendering::CompositeOperation::CLEAR:
+ o_action.meSrcBlendMode=GL_ZERO;
+ o_action.meDstBlendMode=GL_ZERO;
+ break;
+ case rendering::CompositeOperation::SOURCE:
+ o_action.meSrcBlendMode=GL_ONE;
+ o_action.meDstBlendMode=GL_ZERO;
+ break;
+ case rendering::CompositeOperation::UNDER:
+ // FALLTHROUGH intended - but correct?!
+ case rendering::CompositeOperation::DESTINATION:
+ o_action.meSrcBlendMode=GL_ZERO;
+ o_action.meDstBlendMode=GL_ONE;
+ break;
+ case rendering::CompositeOperation::INSIDE:
+ o_action.meSrcBlendMode=GL_DST_ALPHA;
+ o_action.meDstBlendMode=GL_ZERO;
+ break;
+ case rendering::CompositeOperation::INSIDE_REVERSE:
+ o_action.meSrcBlendMode=GL_ONE_MINUS_DST_ALPHA;
+ o_action.meDstBlendMode=GL_ZERO;
+ break;
+ case rendering::CompositeOperation::OUTSIDE:
+ o_action.meSrcBlendMode=GL_ONE_MINUS_DST_ALPHA;
+ o_action.meDstBlendMode=GL_ONE;
+ break;
+ case rendering::CompositeOperation::OUTSIDE_REVERSE:
+ o_action.meSrcBlendMode=GL_ZERO;
+ o_action.meDstBlendMode=GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case rendering::CompositeOperation::ATOP:
+ o_action.meSrcBlendMode=GL_DST_ALPHA;
+ o_action.meDstBlendMode=GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case rendering::CompositeOperation::ATOP_REVERSE:
+ o_action.meSrcBlendMode=GL_ONE_MINUS_DST_ALPHA;
+ o_action.meDstBlendMode=GL_SRC_ALPHA;
+ break;
+ case rendering::CompositeOperation::XOR:
+ o_action.meSrcBlendMode=GL_ONE_MINUS_DST_ALPHA;
+ o_action.meDstBlendMode=GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case rendering::CompositeOperation::ADD:
+ o_action.meSrcBlendMode=GL_ONE;
+ o_action.meDstBlendMode=GL_ONE;
+ break;
+ case rendering::CompositeOperation::SATURATE:
+ o_action.meSrcBlendMode=GL_SRC_ALPHA_SATURATE;
+ o_action.meDstBlendMode=GL_SRC_ALPHA_SATURATE;
+ break;
+
+ default:
+ ENSURE_OR_THROW( false, "CanvasHelper::setupGraphicsState: unexpected mode" );
+ break;
+ }
+
+ o_action.maARGBColor =
+ mpDevice->getDeviceColorSpace()->convertToARGB(renderState.DeviceColor)[0];
+ }
+
+ void CanvasHelper::flush() const
+ {
+ }
+
+ bool CanvasHelper::renderRecordedActions() const
+ {
+ std::vector<Action>::const_iterator aCurr(mpRecordedActions->begin());
+ const std::vector<Action>::const_iterator aEnd(mpRecordedActions->end());
+ while( aCurr != aEnd )
+ {
+ if( !aCurr->maFunction( *this,
+ aCurr->maTransform,
+ aCurr->meSrcBlendMode,
+ aCurr->meDstBlendMode,
+ aCurr->maARGBColor,
+ aCurr->maPolyPolys ) )
+ return false;
+
+ ++aCurr;
+ }
+
+ return true;
+ }
+
+ size_t CanvasHelper::getRecordedActionCount() const
+ {
+ return mpRecordedActions->size();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/opengl/ogl_canvashelper.hxx b/canvas/source/opengl/ogl_canvashelper.hxx
new file mode 100644
index 0000000..b7280ac
--- /dev/null
+++ b/canvas/source/opengl/ogl_canvashelper.hxx
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef OGL_CANVASHELPER_HXX_
+#define OGL_CANVASHELPER_HXX_
+
+#include <com/sun/star/rendering/XCanvas.hpp>
+
+#include <basegfx/vector/b2isize.hxx>
+#include <basegfx/vector/b2dsize.hxx>
+
+#include <o3tl/cow_wrapper.hxx>
+#include <vector>
+
+namespace oglcanvas
+{
+ class SpriteDeviceHelper;
+
+ /** Helper class for basic canvas functionality. */
+ class CanvasHelper
+ {
+ public:
+ CanvasHelper();
+
+ // outline because of incomplete type Action
+ ~CanvasHelper();
+ CanvasHelper& operator=( const CanvasHelper& );
+
+ /// Release all references
+ void disposing();
+
+ /** Initialize canvas helper
+
+ This method late-initializes the canvas helper, providing
+ it with the necessary device and output objects. Note that
+ the CanvasHelper does <em>not</em> take ownership of the
+ passed rDevice reference, nor does it perform any
+ reference counting. Thus, to prevent the reference counted
+ SpriteCanvas object from deletion, the user of this class
+ is responsible for holding ref-counted references itself!
+
+ @param rDevice
+ Reference device this canvas is associated with
+
+ */
+ void init( ::com::sun::star::rendering::XGraphicDevice& rDevice,
+ SpriteDeviceHelper& rDeviceHelper );
+
+ // CanvasHelper functionality
+ // ==========================
+
+ // XCanvas (only providing, not implementing the
+ // interface. Also note subtle method parameter differences)
+ void clear();
+ void drawPoint( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::geometry::RealPoint2D& aPoint,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState );
+ void drawLine( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::geometry::RealPoint2D& aStartPoint,
+ const ::com::sun::star::geometry::RealPoint2D& aEndPoint,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState );
+ void drawBezier( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::geometry::RealBezierSegment2D& aBezierSegment,
+ const ::com::sun::star::geometry::RealPoint2D& aEndPoint,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState );
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCachedPrimitive >
+ drawPolyPolygon( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState );
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCachedPrimitive >
+ strokePolyPolygon( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState,
+ const ::com::sun::star::rendering::StrokeAttributes& strokeAttributes );
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCachedPrimitive >
+ strokeTexturedPolyPolygon( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::rendering::Texture >& textures,
+ const ::com::sun::star::rendering::StrokeAttributes& strokeAttributes );
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCachedPrimitive >
+ strokeTextureMappedPolyPolygon( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::rendering::Texture >& textures,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::geometry::XMapping2D >& xMapping,
+ const ::com::sun::star::rendering::StrokeAttributes& strokeAttributes );
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >
+ queryStrokeShapes( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState,
+ const ::com::sun::star::rendering::StrokeAttributes& strokeAttributes );
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCachedPrimitive >
+ fillPolyPolygon( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState );
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCachedPrimitive >
+ fillTexturedPolyPolygon( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::rendering::Texture >& textures );
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCachedPrimitive >
+ fillTextureMappedPolyPolygon( const ::com::sun::star::rendering::XCanvas* pCanvas,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
+ const ::com::sun::star::rendering::ViewState& viewState,
+ const ::com::sun::star::rendering::RenderState& renderState,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::rendering::Texture >& textures,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::geometry::XMapping2D >& xMapping );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvasFont > SAL_CALL
+ createFont( const ::com::sun::star::rendering::XCanvas* pCanvas,
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list