| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "precompiled_sd.hxx" |
| |
| #include "PresenterCanvas.hxx" |
| |
| #include <basegfx/matrix/b2dhommatrix.hxx> |
| #include <basegfx/polygon/b2dpolygontools.hxx> |
| #include <basegfx/polygon/b2dpolypolygon.hxx> |
| #include <basegfx/polygon/b2dpolygonclipper.hxx> |
| #include <basegfx/range/b2drectangle.hxx> |
| #include <basegfx/tools/canvastools.hxx> |
| #include <canvas/canvastools.hxx> |
| #include <cppuhelper/basemutex.hxx> |
| #include <cppuhelper/compbase1.hxx> |
| #include <rtl/ref.hxx> |
| #include <toolkit/helper/vclunohelper.hxx> |
| #include <vcl/window.hxx> |
| #include <vcl/svapp.hxx> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using ::rtl::OUString; |
| |
| namespace sd { namespace presenter { |
| |
| //===== Service =============================================================== |
| |
| Reference<XInterface> SAL_CALL PresenterCanvas_createInstance ( |
| const Reference<XComponentContext>& rxContext) |
| { |
| (void)rxContext; |
| return Reference<XInterface>(static_cast<XWeak*>(new PresenterCanvas())); |
| } |
| |
| |
| |
| |
| ::rtl::OUString PresenterCanvas_getImplementationName (void) throw(RuntimeException) |
| { |
| return OUString::createFromAscii("com.sun.star.comp.Draw.PresenterCanvasFactory"); |
| } |
| |
| |
| |
| |
| Sequence<rtl::OUString> SAL_CALL PresenterCanvas_getSupportedServiceNames (void) |
| throw (RuntimeException) |
| { |
| static const ::rtl::OUString sServiceName( |
| ::rtl::OUString::createFromAscii("com.sun.star.rendering.Canvas")); |
| return Sequence<rtl::OUString>(&sServiceName, 1); |
| } |
| |
| |
| |
| |
| //===== PresenterCustomSprite ================================================= |
| |
| /** Wrapper around a sprite that is displayed on a PresenterCanvas. |
| */ |
| namespace { |
| typedef ::cppu::WeakComponentImplHelper1 < |
| css::rendering::XCustomSprite |
| > PresenterCustomSpriteInterfaceBase; |
| } |
| class PresenterCustomSprite |
| : private ::boost::noncopyable, |
| protected ::cppu::BaseMutex, |
| public PresenterCustomSpriteInterfaceBase |
| { |
| public: |
| PresenterCustomSprite ( |
| const rtl::Reference<PresenterCanvas>& rpCanvas, |
| const Reference<rendering::XCustomSprite>& rxSprite, |
| const Reference<awt::XWindow>& rxBaseWindow, |
| const css::geometry::RealSize2D& rSpriteSize); |
| virtual ~PresenterCustomSprite (void); |
| virtual void SAL_CALL disposing (void) |
| throw (RuntimeException); |
| |
| // XSprite |
| |
| virtual void SAL_CALL setAlpha (double nAlpha) |
| throw (lang::IllegalArgumentException,RuntimeException); |
| |
| virtual void SAL_CALL move (const geometry::RealPoint2D& rNewPos, |
| const rendering::ViewState& rViewState, |
| const rendering::RenderState& rRenderState) |
| throw (lang::IllegalArgumentException,RuntimeException); |
| |
| virtual void SAL_CALL transform (const geometry::AffineMatrix2D& rTransformation) |
| throw (lang::IllegalArgumentException,RuntimeException); |
| |
| virtual void SAL_CALL clip (const Reference<rendering::XPolyPolygon2D>& rClip) |
| throw (RuntimeException); |
| |
| virtual void SAL_CALL setPriority (double nPriority) |
| throw (RuntimeException); |
| |
| virtual void SAL_CALL show (void) |
| throw (RuntimeException); |
| |
| virtual void SAL_CALL hide (void) |
| throw (RuntimeException); |
| |
| |
| // XCustomSprite |
| |
| virtual Reference<rendering::XCanvas> SAL_CALL getContentCanvas (void) |
| throw (RuntimeException); |
| |
| private: |
| rtl::Reference<PresenterCanvas> mpCanvas; |
| Reference<rendering::XCustomSprite> mxSprite; |
| Reference<awt::XWindow> mxBaseWindow; |
| geometry::RealPoint2D maPosition; |
| geometry::RealSize2D maSpriteSize; |
| |
| void ThrowIfDisposed (void) |
| throw (css::lang::DisposedException); |
| }; |
| |
| |
| |
| |
| //===== PresenterCanvas ======================================================= |
| |
| |
| PresenterCanvas::PresenterCanvas (void) |
| : PresenterCanvasInterfaceBase(m_aMutex), |
| mxUpdateCanvas(), |
| mxSharedCanvas(), |
| mxSharedWindow(), |
| mxWindow(), |
| maOffset(), |
| mpUpdateRequester(), |
| maClipRectangle(), |
| mbOffsetUpdatePending(true) |
| { |
| } |
| |
| |
| |
| |
| PresenterCanvas::PresenterCanvas ( |
| const Reference<rendering::XSpriteCanvas>& rxUpdateCanvas, |
| const Reference<awt::XWindow>& rxUpdateWindow, |
| const Reference<rendering::XCanvas>& rxSharedCanvas, |
| const Reference<awt::XWindow>& rxSharedWindow, |
| const Reference<awt::XWindow>& rxWindow) |
| : PresenterCanvasInterfaceBase(m_aMutex), |
| mxUpdateCanvas(rxUpdateCanvas), |
| mxUpdateWindow(rxUpdateWindow), |
| mxSharedCanvas(rxSharedCanvas), |
| mxSharedWindow(rxSharedWindow), |
| mxWindow(rxWindow), |
| maOffset(), |
| mpUpdateRequester(), |
| maClipRectangle(), |
| mbOffsetUpdatePending(true) |
| { |
| if (mxWindow.is()) |
| mxWindow->addWindowListener(this); |
| |
| if (mxUpdateCanvas.is()) |
| mpUpdateRequester = CanvasUpdateRequester::Instance(mxUpdateCanvas); |
| } |
| |
| |
| |
| |
| PresenterCanvas::~PresenterCanvas (void) |
| { |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCanvas::disposing (void) |
| throw (css::uno::RuntimeException) |
| { |
| if (mxWindow.is()) |
| mxWindow->removeWindowListener(this); |
| } |
| |
| |
| |
| |
| //----- XInitialization ------------------------------------------------------- |
| |
| void SAL_CALL PresenterCanvas::initialize ( |
| const Sequence<Any>& rArguments) |
| throw(Exception, RuntimeException) |
| { |
| if (rBHelper.bDisposed || rBHelper.bInDispose) |
| ThrowIfDisposed(); |
| |
| if (rArguments.getLength() == 5) |
| { |
| try |
| { |
| // First and second argument may be NULL. |
| rArguments[0] >>= mxUpdateCanvas; |
| rArguments[1] >>= mxUpdateWindow; |
| |
| if ( ! (rArguments[2] >>= mxSharedWindow)) |
| { |
| throw lang::IllegalArgumentException( |
| OUString::createFromAscii("PresenterCanvas: invalid shared window"), |
| static_cast<XWeak*>(this), |
| 1); |
| } |
| |
| if ( ! (rArguments[3] >>= mxSharedCanvas)) |
| { |
| throw lang::IllegalArgumentException( |
| OUString::createFromAscii("PresenterCanvas: invalid shared canvas"), |
| static_cast<XWeak*>(this), |
| 2); |
| } |
| |
| if ( ! (rArguments[4] >>= mxWindow)) |
| { |
| throw lang::IllegalArgumentException( |
| OUString::createFromAscii("PresenterCanvas: invalid window"), |
| static_cast<XWeak*>(this), |
| 3); |
| } |
| |
| mpUpdateRequester = CanvasUpdateRequester::Instance(mxUpdateCanvas); |
| |
| mbOffsetUpdatePending = true; |
| if (mxWindow.is()) |
| mxWindow->addWindowListener(this); |
| } |
| catch (RuntimeException&) |
| { |
| mxSharedWindow = NULL; |
| mxWindow = NULL; |
| throw; |
| } |
| } |
| else |
| { |
| throw RuntimeException( |
| OUString::createFromAscii("PresenterCanvas: invalid number of arguments"), |
| static_cast<XWeak*>(this)); |
| } |
| } |
| |
| |
| |
| |
| //----- XCanvas --------------------------------------------------------------- |
| |
| void SAL_CALL PresenterCanvas::clear (void) |
| throw (css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| // ToDo: Clear the area covered by the child window. A simple forward |
| // would clear the whole shared canvas. |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCanvas::drawPoint ( |
| const css::geometry::RealPoint2D& aPoint, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mxSharedCanvas->drawPoint(aPoint,MergeViewState(aViewState),aRenderState); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCanvas::drawLine ( |
| const css::geometry::RealPoint2D& aStartPoint, |
| const css::geometry::RealPoint2D& aEndPoint, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mxSharedCanvas->drawLine(aStartPoint,aEndPoint,MergeViewState(aViewState),aRenderState); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCanvas::drawBezier ( |
| const css::geometry::RealBezierSegment2D& aBezierSegment, |
| const css::geometry::RealPoint2D& aEndPoint, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mxSharedCanvas->drawBezier(aBezierSegment,aEndPoint,MergeViewState(aViewState),aRenderState); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL PresenterCanvas::drawPolyPolygon ( |
| const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->drawPolyPolygon( |
| xPolyPolygon, MergeViewState(aViewState), aRenderState); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL PresenterCanvas::strokePolyPolygon ( |
| const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState, |
| const css::rendering::StrokeAttributes& aStrokeAttributes) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->strokePolyPolygon( |
| xPolyPolygon, MergeViewState(aViewState), aRenderState, aStrokeAttributes); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::strokeTexturedPolyPolygon ( |
| const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState, |
| const css::uno::Sequence< css::rendering::Texture >& aTextures, |
| const css::rendering::StrokeAttributes& aStrokeAttributes) |
| throw (css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->strokeTexturedPolyPolygon( |
| xPolyPolygon, MergeViewState(aViewState), aRenderState, aTextures, aStrokeAttributes); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::strokeTextureMappedPolyPolygon( |
| const css::uno::Reference<css::rendering::XPolyPolygon2D >& xPolyPolygon, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState, |
| const css::uno::Sequence<css::rendering::Texture>& aTextures, |
| const css::uno::Reference<css::geometry::XMapping2D>& xMapping, |
| const css::rendering::StrokeAttributes& aStrokeAttributes) |
| throw (css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->strokeTextureMappedPolyPolygon( |
| xPolyPolygon, |
| MergeViewState(aViewState), |
| aRenderState, |
| aTextures, |
| xMapping, |
| aStrokeAttributes); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XPolyPolygon2D> SAL_CALL |
| PresenterCanvas::queryStrokeShapes( |
| const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState, |
| const css::rendering::StrokeAttributes& aStrokeAttributes) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->queryStrokeShapes( |
| xPolyPolygon, MergeViewState(aViewState), aRenderState, aStrokeAttributes); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::fillPolyPolygon( |
| const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState) |
| throw (css::lang::IllegalArgumentException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->fillPolyPolygon( |
| xPolyPolygon, MergeViewState(aViewState), aRenderState); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::fillTexturedPolyPolygon( |
| const css::uno::Reference<css::rendering::XPolyPolygon2D>& xPolyPolygon, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState, |
| const css::uno::Sequence<css::rendering::Texture>& xTextures) |
| throw (css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->fillTexturedPolyPolygon( |
| xPolyPolygon, MergeViewState(aViewState), aRenderState, xTextures); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::fillTextureMappedPolyPolygon( |
| const css::uno::Reference< css::rendering::XPolyPolygon2D >& xPolyPolygon, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState, |
| const css::uno::Sequence< css::rendering::Texture >& xTextures, |
| const css::uno::Reference< css::geometry::XMapping2D >& xMapping) |
| throw (css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->fillTextureMappedPolyPolygon( |
| xPolyPolygon, MergeViewState(aViewState), aRenderState, xTextures, xMapping); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCanvasFont> SAL_CALL |
| PresenterCanvas::createFont( |
| const css::rendering::FontRequest& aFontRequest, |
| const css::uno::Sequence< css::beans::PropertyValue >& aExtraFontProperties, |
| const css::geometry::Matrix2D& aFontMatrix) |
| throw (css::lang::IllegalArgumentException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->createFont( |
| aFontRequest, aExtraFontProperties, aFontMatrix); |
| } |
| |
| |
| |
| |
| css::uno::Sequence<css::rendering::FontInfo> SAL_CALL |
| PresenterCanvas::queryAvailableFonts( |
| const css::rendering::FontInfo& aFilter, |
| const css::uno::Sequence< css::beans::PropertyValue >& aFontProperties) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->queryAvailableFonts(aFilter, aFontProperties); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::drawText( |
| const css::rendering::StringContext& aText, |
| const css::uno::Reference< css::rendering::XCanvasFont >& xFont, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState, |
| ::sal_Int8 nTextDirection) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->drawText( |
| aText, xFont, MergeViewState(aViewState), aRenderState, nTextDirection); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::drawTextLayout( |
| const css::uno::Reference< css::rendering::XTextLayout >& xLayoutetText, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->drawTextLayout( |
| xLayoutetText, MergeViewState(aViewState), aRenderState); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::drawBitmap( |
| const css::uno::Reference< css::rendering::XBitmap >& xBitmap, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState) |
| throw (css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->drawBitmap( |
| xBitmap, MergeViewState(aViewState), aRenderState); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XCachedPrimitive> SAL_CALL |
| PresenterCanvas::drawBitmapModulated( |
| const css::uno::Reference< css::rendering::XBitmap>& xBitmap, |
| const css::rendering::ViewState& aViewState, |
| const css::rendering::RenderState& aRenderState) |
| throw (css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->drawBitmapModulated( |
| xBitmap, MergeViewState(aViewState), aRenderState); |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XGraphicDevice> SAL_CALL |
| PresenterCanvas::getDevice (void) |
| throw (css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSharedCanvas->getDevice(); |
| } |
| |
| |
| |
| |
| //----- XBitmapCanvas --------------------------------------------------------- |
| |
| void SAL_CALL PresenterCanvas::copyRect( |
| const css::uno::Reference<css::rendering::XBitmapCanvas>& rxSourceCanvas, |
| const css::geometry::RealRectangle2D& rSourceRect, |
| const css::rendering::ViewState& rSourceViewState, |
| const css::rendering::RenderState& rSourceRenderState, |
| const css::geometry::RealRectangle2D& rDestRect, |
| const css::rendering::ViewState& rDestViewState, |
| const css::rendering::RenderState& rDestRenderState) |
| throw (css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| Reference<rendering::XBitmapCanvas> xBitmapCanvas (mxSharedCanvas, UNO_QUERY); |
| if (xBitmapCanvas.is()) |
| { |
| rendering::ViewState aSourceViewState (rSourceViewState); |
| if (rxSourceCanvas == Reference<rendering::XCanvas>(this)) |
| aSourceViewState = MergeViewState(aSourceViewState); |
| xBitmapCanvas->copyRect( |
| rxSourceCanvas, rSourceRect, aSourceViewState, rSourceRenderState, |
| rDestRect, MergeViewState(rDestViewState), rDestRenderState); |
| } |
| } |
| |
| |
| |
| |
| //----- XSpriteCanvas --------------------------------------------------------- |
| |
| Reference<rendering::XAnimatedSprite> SAL_CALL |
| PresenterCanvas::createSpriteFromAnimation ( |
| const css::uno::Reference<css::rendering::XAnimation>& rAnimation) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxSharedCanvas, UNO_QUERY); |
| if (xSpriteCanvas.is()) |
| return xSpriteCanvas->createSpriteFromAnimation(rAnimation); |
| else |
| return NULL; |
| } |
| |
| |
| |
| |
| Reference<rendering::XAnimatedSprite> SAL_CALL |
| PresenterCanvas::createSpriteFromBitmaps ( |
| const css::uno::Sequence< |
| css::uno::Reference< css::rendering::XBitmap > >& rAnimationBitmaps, |
| ::sal_Int8 nInterpolationMode) |
| throw (css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException, |
| css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxSharedCanvas, UNO_QUERY); |
| if (xSpriteCanvas.is()) |
| return xSpriteCanvas->createSpriteFromBitmaps(rAnimationBitmaps, nInterpolationMode); |
| else |
| return NULL; |
| } |
| |
| |
| |
| |
| Reference<rendering::XCustomSprite> SAL_CALL |
| PresenterCanvas::createCustomSprite ( |
| const css::geometry::RealSize2D& rSpriteSize) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxSharedCanvas, UNO_QUERY); |
| if (xSpriteCanvas.is()) |
| return new PresenterCustomSprite( |
| this, |
| xSpriteCanvas->createCustomSprite(rSpriteSize), |
| mxSharedWindow, |
| rSpriteSize); |
| else if (mxUpdateCanvas.is()) |
| return new PresenterCustomSprite( |
| this, |
| mxUpdateCanvas->createCustomSprite(rSpriteSize), |
| mxUpdateWindow, |
| rSpriteSize); |
| else |
| return NULL; |
| } |
| |
| |
| |
| |
| Reference<rendering::XSprite> SAL_CALL |
| PresenterCanvas::createClonedSprite ( |
| const css::uno::Reference< css::rendering::XSprite >& rxOriginal) |
| throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxSharedCanvas, UNO_QUERY); |
| if (xSpriteCanvas.is()) |
| return xSpriteCanvas->createClonedSprite(rxOriginal); |
| if (mxUpdateCanvas.is()) |
| return mxUpdateCanvas->createClonedSprite(rxOriginal); |
| return NULL; |
| } |
| |
| |
| |
| |
| ::sal_Bool SAL_CALL PresenterCanvas::updateScreen (::sal_Bool bUpdateAll) |
| throw (css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| mbOffsetUpdatePending = true; |
| if (mpUpdateRequester.get() != NULL) |
| { |
| mpUpdateRequester->RequestUpdate(bUpdateAll); |
| return sal_True; |
| } |
| else |
| { |
| return sal_False; |
| } |
| } |
| |
| |
| |
| |
| //----- XEventListener -------------------------------------------------------- |
| |
| void SAL_CALL PresenterCanvas::disposing (const css::lang::EventObject& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| ThrowIfDisposed(); |
| if (rEvent.Source == mxWindow) |
| mxWindow = NULL; |
| } |
| |
| |
| |
| |
| //----- XWindowListener ------------------------------------------------------- |
| |
| void SAL_CALL PresenterCanvas::windowResized (const css::awt::WindowEvent& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| ThrowIfDisposed(); |
| mbOffsetUpdatePending = true; |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCanvas::windowMoved (const css::awt::WindowEvent& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| ThrowIfDisposed(); |
| mbOffsetUpdatePending = true; |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCanvas::windowShown (const css::lang::EventObject& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| ThrowIfDisposed(); |
| mbOffsetUpdatePending = true; |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCanvas::windowHidden (const css::lang::EventObject& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| ThrowIfDisposed(); |
| } |
| |
| |
| |
| |
| //----- XBitmap --------------------------------------------------------------- |
| |
| geometry::IntegerSize2D SAL_CALL PresenterCanvas::getSize (void) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| if (mxWindow.is()) |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| return geometry::IntegerSize2D(aWindowBox.Width, aWindowBox.Height); |
| } |
| else |
| return geometry::IntegerSize2D(0,0); |
| } |
| |
| |
| |
| |
| sal_Bool SAL_CALL PresenterCanvas::hasAlpha (void) |
| throw (RuntimeException) |
| { |
| Reference<rendering::XBitmap> xBitmap (mxSharedCanvas, UNO_QUERY); |
| if (xBitmap.is()) |
| return xBitmap->hasAlpha(); |
| else |
| return sal_False; |
| } |
| |
| |
| |
| |
| Reference<rendering::XBitmapCanvas> SAL_CALL PresenterCanvas::queryBitmapCanvas (void) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| return this; |
| } |
| |
| |
| |
| |
| Reference<rendering::XBitmap> SAL_CALL PresenterCanvas::getScaledBitmap( |
| const css::geometry::RealSize2D& rNewSize, |
| sal_Bool bFast) |
| throw (css::uno::RuntimeException, |
| css::lang::IllegalArgumentException, |
| css::rendering::VolatileContentDestroyedException) |
| { |
| (void)rNewSize; |
| (void)bFast; |
| |
| ThrowIfDisposed(); |
| |
| // Not implemented. |
| |
| return NULL; |
| } |
| |
| |
| |
| |
| //----------------------------------------------------------------------------- |
| |
| rendering::ViewState PresenterCanvas::MergeViewState ( |
| const rendering::ViewState& rViewState) |
| { |
| // Make sure the offset is up-to-date. |
| if (mbOffsetUpdatePending) |
| maOffset = GetOffset(mxSharedWindow); |
| return MergeViewState(rViewState, maOffset); |
| } |
| |
| |
| |
| |
| css::rendering::ViewState PresenterCanvas::MergeViewState ( |
| const css::rendering::ViewState& rViewState, |
| const css::awt::Point& rOffset) |
| { |
| // Early rejects. |
| if ( ! mxSharedCanvas.is()) |
| return rViewState; |
| |
| Reference<rendering::XGraphicDevice> xDevice (mxSharedCanvas->getDevice()); |
| if ( ! xDevice.is()) |
| return rViewState; |
| |
| // Create a modifiable copy of the given view state. |
| rendering::ViewState aViewState (rViewState); |
| |
| // Prepare the local clip rectangle. |
| ::basegfx::B2DRectangle aWindowRange (GetClipRectangle(aViewState.AffineTransform, rOffset)); |
| |
| // Adapt the offset of the view state. |
| aViewState.AffineTransform.m02 += rOffset.X; |
| aViewState.AffineTransform.m12 += rOffset.Y; |
| |
| // Adapt the clip polygon. |
| if ( ! aViewState.Clip.is()) |
| { |
| // Cancel out the later multiplication with the view state |
| // transformation. |
| aViewState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( |
| xDevice, |
| ::basegfx::B2DPolyPolygon(::basegfx::tools::createPolygonFromRect(aWindowRange))); |
| } |
| else |
| { |
| // Have to compute the intersection of the given clipping polygon in |
| // the view state and the local clip rectangle. |
| |
| // Clip the view state clipping polygon against the local clip rectangle. |
| const ::basegfx::B2DPolyPolygon aClipPolygon ( |
| ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( |
| aViewState.Clip)); |
| const ::basegfx::B2DPolyPolygon aClippedClipPolygon ( |
| ::basegfx::tools::clipPolyPolygonOnRange( |
| aClipPolygon, |
| aWindowRange, |
| true, /* bInside */ |
| false /* bStroke */)); |
| |
| aViewState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( |
| xDevice, |
| aClippedClipPolygon); |
| } |
| |
| return aViewState; |
| } |
| |
| |
| |
| |
| awt::Point PresenterCanvas::GetOffset (const Reference<awt::XWindow>& rxBaseWindow) |
| { |
| mbOffsetUpdatePending = false; |
| if (mxWindow.is() && rxBaseWindow.is()) |
| { |
| ::Window* pWindow = VCLUnoHelper::GetWindow(mxWindow); |
| ::Window* pSharedWindow = VCLUnoHelper::GetWindow(rxBaseWindow); |
| if (pWindow!=NULL && pSharedWindow!=NULL) |
| { |
| Rectangle aBox = pWindow->GetWindowExtentsRelative(pSharedWindow); |
| |
| // Calculate offset of this canvas with respect to the shared |
| // canvas. |
| return awt::Point(aBox.Left(), aBox.Top()); |
| } |
| } |
| |
| return awt::Point(0, 0); |
| } |
| |
| |
| |
| |
| ::basegfx::B2DRectangle PresenterCanvas::GetClipRectangle ( |
| const css::geometry::AffineMatrix2D& rViewTransform, |
| const awt::Point& rOffset) |
| { |
| ::basegfx::B2DRectangle aClipRectangle; |
| |
| ::Window* pWindow = VCLUnoHelper::GetWindow(mxWindow); |
| if (pWindow == NULL) |
| return ::basegfx::B2DRectangle(); |
| |
| ::Window* pSharedWindow = VCLUnoHelper::GetWindow(mxSharedWindow); |
| if (pSharedWindow == NULL) |
| return ::basegfx::B2DRectangle(); |
| |
| // Get the bounding box of the window and create a range in the |
| // coordinate system of the child window. |
| Rectangle aLocalClip; |
| if (maClipRectangle.Width <= 0 || maClipRectangle.Height <= 0) |
| { |
| // No clip rectangle has been set via SetClip by the pane. |
| // Use the window extents instead. |
| aLocalClip = pWindow->GetWindowExtentsRelative(pSharedWindow); |
| } |
| else |
| { |
| // Use a previously given clip rectangle. |
| aLocalClip = Rectangle( |
| maClipRectangle.X + rOffset.X, |
| maClipRectangle.Y + rOffset.Y, |
| maClipRectangle.X + maClipRectangle.Width + rOffset.X, |
| maClipRectangle.Y + maClipRectangle.Height + rOffset.Y); |
| } |
| |
| // The local clip rectangle is used to clip the view state clipping |
| // polygon. |
| ::basegfx::B2DRectangle aWindowRectangle ( |
| aLocalClip.Left() - rOffset.X, |
| aLocalClip.Top() - rOffset.Y, |
| aLocalClip.Right() - rOffset.X + 1, |
| aLocalClip.Bottom() - rOffset.Y + 1); |
| |
| // Calculate the inverted view state transformation to cancel out a |
| // later transformation of the local clip polygon with the view state |
| // transformation. |
| ::basegfx::B2DHomMatrix aInvertedViewStateTransformation; |
| ::basegfx::unotools::homMatrixFromAffineMatrix( |
| aInvertedViewStateTransformation, |
| rViewTransform); |
| if (aInvertedViewStateTransformation.invert()) |
| { |
| // Cancel out the later multiplication with the view state |
| // transformation. |
| aWindowRectangle.transform(aInvertedViewStateTransformation); |
| } |
| |
| return aWindowRectangle; |
| } |
| |
| |
| |
| Reference<rendering::XPolyPolygon2D> PresenterCanvas::UpdateSpriteClip ( |
| const Reference<rendering::XPolyPolygon2D>& rxOriginalClip, |
| const geometry::RealPoint2D& rLocation, |
| const geometry::RealSize2D& rSize) |
| { |
| (void)rSize; |
| |
| // Check used resources and just return the original clip when not |
| // every one of them is available. |
| if ( ! mxWindow.is()) |
| return rxOriginalClip; |
| |
| Reference<rendering::XGraphicDevice> xDevice (mxSharedCanvas->getDevice()); |
| if ( ! xDevice.is()) |
| return rxOriginalClip; |
| |
| // Determine the bounds of the clip rectangle (the window border) in the |
| // coordinate system of the sprite. |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| const double nMinX (-rLocation.X); |
| const double nMinY (-rLocation.Y); |
| const double nMaxX (aWindowBox.Width-rLocation.X); |
| const double nMaxY (aWindowBox.Height-rLocation.Y); |
| |
| // Create a clip polygon. |
| Reference<rendering::XPolyPolygon2D> xPolygon; |
| if (rxOriginalClip.is()) |
| { |
| // Combine the original clip with the window clip. |
| const ::basegfx::B2DPolyPolygon aOriginalClip ( |
| ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rxOriginalClip)); |
| ::basegfx::B2DRectangle aWindowRange (nMinX, nMinY, nMaxX, nMaxY); |
| const ::basegfx::B2DPolyPolygon aClippedClipPolygon ( |
| ::basegfx::tools::clipPolyPolygonOnRange( |
| aOriginalClip, |
| aWindowRange, |
| true, /* bInside */ |
| false /* bStroke */)); |
| xPolygon = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( |
| xDevice, |
| aClippedClipPolygon); |
| } |
| else |
| { |
| // Create a new clip polygon from the window clip rectangle. |
| Sequence<Sequence<geometry::RealPoint2D> > aPoints (1); |
| aPoints[0] = Sequence<geometry::RealPoint2D>(4); |
| aPoints[0][0] = geometry::RealPoint2D(nMinX,nMinY); |
| aPoints[0][1] = geometry::RealPoint2D(nMaxX,nMinY); |
| aPoints[0][2] = geometry::RealPoint2D(nMaxX,nMaxY); |
| aPoints[0][3] = geometry::RealPoint2D(nMinX,nMaxY); |
| Reference<rendering::XLinePolyPolygon2D> xLinePolygon( |
| xDevice->createCompatibleLinePolyPolygon(aPoints)); |
| if (xLinePolygon.is()) |
| xLinePolygon->setClosed(0, sal_True); |
| xPolygon = Reference<rendering::XPolyPolygon2D>(xLinePolygon, UNO_QUERY); |
| } |
| |
| return xPolygon; |
| } |
| |
| |
| |
| |
| void PresenterCanvas::ThrowIfDisposed (void) |
| throw (css::lang::DisposedException) |
| { |
| if (rBHelper.bDisposed || rBHelper.bInDispose || ! mxSharedCanvas.is()) |
| { |
| throw lang::DisposedException ( |
| ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( |
| "PresenterCanvas object has already been disposed")), |
| static_cast<uno::XWeak*>(this)); |
| } |
| } |
| |
| |
| |
| |
| //===== PresenterCustomSprite ================================================= |
| |
| |
| PresenterCustomSprite::PresenterCustomSprite ( |
| const rtl::Reference<PresenterCanvas>& rpCanvas, |
| const Reference<rendering::XCustomSprite>& rxSprite, |
| const Reference<awt::XWindow>& rxBaseWindow, |
| const css::geometry::RealSize2D& rSpriteSize) |
| : PresenterCustomSpriteInterfaceBase(m_aMutex), |
| mpCanvas(rpCanvas), |
| mxSprite(rxSprite), |
| mxBaseWindow(rxBaseWindow), |
| maPosition(0,0), |
| maSpriteSize(rSpriteSize) |
| { |
| } |
| |
| |
| |
| |
| PresenterCustomSprite::~PresenterCustomSprite (void) |
| { |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCustomSprite::disposing (void) |
| throw (RuntimeException) |
| { |
| Reference<XComponent> xComponent (mxSprite, UNO_QUERY); |
| mxSprite = NULL; |
| if (xComponent.is()) |
| xComponent->dispose(); |
| mpCanvas = rtl::Reference<PresenterCanvas>(); |
| } |
| |
| |
| |
| |
| //----- XSprite --------------------------------------------------------------- |
| |
| void SAL_CALL PresenterCustomSprite::setAlpha (const double nAlpha) |
| throw (lang::IllegalArgumentException,RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mxSprite->setAlpha(nAlpha); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCustomSprite::move ( |
| const geometry::RealPoint2D& rNewPos, |
| const rendering::ViewState& rViewState, |
| const rendering::RenderState& rRenderState) |
| throw (lang::IllegalArgumentException,RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maPosition = rNewPos; |
| mxSprite->move( |
| rNewPos, |
| mpCanvas->MergeViewState(rViewState, mpCanvas->GetOffset(mxBaseWindow)), |
| rRenderState); |
| // Clip sprite against window bounds. This call is necessary because |
| // sprite clipping is done in the corrdinate system of the sprite. |
| // Therefore, after each change of the sprites location the window |
| // bounds have to be transformed into the sprites coordinate system. |
| clip(NULL); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCustomSprite::transform (const geometry::AffineMatrix2D& rTransformation) |
| throw (lang::IllegalArgumentException,RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mxSprite->transform(rTransformation); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCustomSprite::clip (const Reference<rendering::XPolyPolygon2D>& rxClip) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| // The clip region is expected in the coordinate system of the sprite. |
| // UpdateSpriteClip() integrates the window bounds, transformed into the |
| // sprites coordinate system, with the given clip. |
| mxSprite->clip(mpCanvas->UpdateSpriteClip(rxClip, maPosition, maSpriteSize)); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCustomSprite::setPriority (const double nPriority) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mxSprite->setPriority(nPriority); |
| } |
| |
| |
| |
| void SAL_CALL PresenterCustomSprite::show (void) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mxSprite->show(); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterCustomSprite::hide (void) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mxSprite->hide(); |
| } |
| |
| |
| |
| |
| //----- XCustomSprite --------------------------------------------------------- |
| |
| Reference<rendering::XCanvas> PresenterCustomSprite::getContentCanvas (void) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| return mxSprite->getContentCanvas(); |
| } |
| |
| |
| |
| |
| //----------------------------------------------------------------------------- |
| |
| void PresenterCustomSprite::ThrowIfDisposed (void) |
| throw (css::lang::DisposedException) |
| { |
| if (rBHelper.bDisposed || rBHelper.bInDispose || ! mxSprite.is()) |
| { |
| throw lang::DisposedException ( |
| ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( |
| "PresenterCustomSprite object has already been disposed")), |
| static_cast<uno::XWeak*>(this)); |
| } |
| } |
| |
| |
| |
| |
| } } // end of namespace ::sd::presenter |