LCOV - code coverage report
Current view: top level - sdext/source/presenter - PresenterPaneBorderPainter.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 356 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "vcl/svapp.hxx"
      21             : #include "PresenterPaneBorderPainter.hxx"
      22             : #include "PresenterCanvasHelper.hxx"
      23             : #include "PresenterConfigurationAccess.hxx"
      24             : #include "PresenterGeometryHelper.hxx"
      25             : #include "PresenterTheme.hxx"
      26             : #include <com/sun/star/awt/FontDescriptor.hpp>
      27             : #include <com/sun/star/awt/Point.hpp>
      28             : #include <com/sun/star/awt/Rectangle.hpp>
      29             : #include <com/sun/star/awt/SimpleFontMetric.hpp>
      30             : #include <com/sun/star/awt/XFont.hpp>
      31             : #include <com/sun/star/drawing/XPresenterHelper.hpp>
      32             : #include <com/sun/star/graphic/XGraphic.hpp>
      33             : #include <com/sun/star/graphic/XGraphicRenderer.hpp>
      34             : #include <com/sun/star/rendering/CompositeOperation.hpp>
      35             : #include <com/sun/star/rendering/FillRule.hpp>
      36             : #include <com/sun/star/rendering/TextDirection.hpp>
      37             : #include <com/sun/star/rendering/XIntegerBitmap.hpp>
      38             : #include <com/sun/star/rendering/XSpriteCanvas.hpp>
      39             : #include <map>
      40             : #include <vector>
      41             : #include <boost/shared_ptr.hpp>
      42             : 
      43             : using namespace ::com::sun::star;
      44             : using namespace ::com::sun::star::uno;
      45             : 
      46             : namespace sdext { namespace presenter {
      47             : 
      48             : namespace {
      49             :     class BorderSize
      50             :     {
      51             :     public:
      52             :         BorderSize();
      53             :         sal_Int32 mnLeft;
      54             :         sal_Int32 mnTop;
      55             :         sal_Int32 mnRight;
      56             :         sal_Int32 mnBottom;
      57             :     };
      58             : 
      59           0 :     class RendererPaneStyle
      60             :     {
      61             :     public:
      62             :         RendererPaneStyle (
      63             :             const ::boost::shared_ptr<PresenterTheme>& rpTheme,
      64             :             const OUString& rsStyleName);
      65             : 
      66             :         awt::Rectangle AddBorder (
      67             :             const awt::Rectangle& rBox,
      68             :             drawing::framework::BorderType eBorderType) const;
      69             :         awt::Rectangle RemoveBorder (
      70             :             const awt::Rectangle& rBox,
      71             :             drawing::framework::BorderType eBorderType) const;
      72             :         const Reference<rendering::XCanvasFont> GetFont (
      73             :             const Reference<rendering::XCanvas>& rxCanvas) const;
      74             : 
      75             :         SharedBitmapDescriptor mpTopLeft;
      76             :         SharedBitmapDescriptor mpTop;
      77             :         SharedBitmapDescriptor mpTopRight;
      78             :         SharedBitmapDescriptor mpLeft;
      79             :         SharedBitmapDescriptor mpRight;
      80             :         SharedBitmapDescriptor mpBottomLeft;
      81             :         SharedBitmapDescriptor mpBottom;
      82             :         SharedBitmapDescriptor mpBottomRight;
      83             :         SharedBitmapDescriptor mpBottomCallout;
      84             :         SharedBitmapDescriptor mpBackground;
      85             :         SharedBitmapDescriptor mpEmpty;
      86             :         PresenterTheme::SharedFontDescriptor mpFont;
      87             :         sal_Int32 mnFontXOffset;
      88             :         sal_Int32 mnFontYOffset;
      89             :         enum Anchor { AnchorLeft, AnchorRight, AnchorCenter } meFontAnchor;
      90             :         BorderSize maInnerBorderSize;
      91             :         BorderSize maOuterBorderSize;
      92             :         BorderSize maTotalBorderSize;
      93             :         enum Side { Left, Top, Right, Bottom };
      94             :     private:
      95             :         void UpdateBorderSizes();
      96             :         SharedBitmapDescriptor GetBitmap(
      97             :             const ::boost::shared_ptr<PresenterTheme>& rpTheme,
      98             :             const OUString& rsStyleName,
      99             :             const OUString& rsBitmapName);
     100             :     };
     101             : }
     102             : 
     103             : class  PresenterPaneBorderPainter::Renderer
     104             : {
     105             : public:
     106             :     Renderer (
     107             :         const Reference<XComponentContext>& rxContext,
     108             :         const ::boost::shared_ptr<PresenterTheme>& rpTheme);
     109             :     ~Renderer();
     110             : 
     111             :     void SetCanvas (const Reference<rendering::XCanvas>& rxCanvas);
     112             :     void PaintBorder (
     113             :         const OUString& rsTitle,
     114             :         const awt::Rectangle& rBBox,
     115             :         const awt::Rectangle& rUpdateBox,
     116             :         const OUString& rsPaneURL);
     117             :     void PaintTitle (
     118             :         const OUString& rsTitle,
     119             :         const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
     120             :         const awt::Rectangle& rUpdateBox,
     121             :         const awt::Rectangle& rOuterBox,
     122             :         const awt::Rectangle& rInnerBox,
     123             :         const bool bPaintBackground);
     124             :     void SetupClipping (
     125             :         const awt::Rectangle& rUpdateBox,
     126             :         const awt::Rectangle& rOuterBox,
     127             :         const OUString& rsPaneStyleName);
     128             :     ::boost::shared_ptr<RendererPaneStyle> GetRendererPaneStyle (const OUString& rsResourceURL);
     129             :     void SetCalloutAnchor (
     130             :         const awt::Point& rCalloutAnchor);
     131             : 
     132             : private:
     133             :     ::boost::shared_ptr<PresenterTheme> mpTheme;
     134             :     typedef ::std::map<OUString, ::boost::shared_ptr<RendererPaneStyle> > RendererPaneStyleContainer;
     135             :     RendererPaneStyleContainer maRendererPaneStyles;
     136             :     Reference<rendering::XCanvas> mxCanvas;
     137             :     Reference<drawing::XPresenterHelper> mxPresenterHelper;
     138             :     css::rendering::ViewState maViewState;
     139             :     Reference<rendering::XPolyPolygon2D> mxViewStateClip;
     140             :     bool mbHasCallout;
     141             :     awt::Point maCalloutAnchor;
     142             : 
     143             :     void PaintBitmap(
     144             :         const awt::Rectangle& rBox,
     145             :         const awt::Rectangle& rUpdateBox,
     146             :         const sal_Int32 nXPosition,
     147             :         const sal_Int32 nYPosition,
     148             :         const sal_Int32 nStartOffset,
     149             :         const sal_Int32 nEndOffset,
     150             :         const bool bExpand,
     151             :         const SharedBitmapDescriptor& rpBitmap,
     152             :         const SharedBitmapDescriptor& rpBackgroundBitmap);
     153             : };
     154             : 
     155             : // ===== PresenterPaneBorderPainter ===========================================
     156             : 
     157           0 : PresenterPaneBorderPainter::PresenterPaneBorderPainter (
     158             :     const Reference<XComponentContext>& rxContext)
     159             :     : PresenterPaneBorderPainterInterfaceBase(m_aMutex),
     160             :       mxContext(rxContext),
     161             :       mpTheme(),
     162           0 :       mpRenderer()
     163             : {
     164           0 : }
     165             : 
     166           0 : PresenterPaneBorderPainter::~PresenterPaneBorderPainter()
     167             : {
     168           0 : }
     169             : 
     170             : //----- XPaneBorderPainter ----------------------------------------------------
     171             : 
     172           0 : awt::Rectangle SAL_CALL PresenterPaneBorderPainter::addBorder (
     173             :     const OUString& rsPaneBorderStyleName,
     174             :     const css::awt::Rectangle& rRectangle,
     175             :     drawing::framework::BorderType eBorderType)
     176             :     throw(css::uno::RuntimeException, std::exception)
     177             : {
     178           0 :     ThrowIfDisposed();
     179             : 
     180           0 :     ProvideTheme();
     181             : 
     182           0 :     return AddBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
     183             : }
     184             : 
     185           0 : awt::Rectangle SAL_CALL PresenterPaneBorderPainter::removeBorder (
     186             :     const OUString& rsPaneBorderStyleName,
     187             :     const css::awt::Rectangle& rRectangle,
     188             :     drawing::framework::BorderType eBorderType)
     189             :     throw(css::uno::RuntimeException, std::exception)
     190             : {
     191           0 :     ThrowIfDisposed();
     192             : 
     193           0 :     ProvideTheme();
     194             : 
     195           0 :     return RemoveBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
     196             : }
     197             : 
     198           0 : void SAL_CALL PresenterPaneBorderPainter::paintBorder (
     199             :     const OUString& rsPaneBorderStyleName,
     200             :     const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
     201             :     const css::awt::Rectangle& rOuterBorderRectangle,
     202             :     const css::awt::Rectangle& rRepaintArea,
     203             :     const OUString& rsTitle)
     204             :     throw(css::uno::RuntimeException, std::exception)
     205             : {
     206           0 :     ThrowIfDisposed();
     207             : 
     208             :     // Early reject paints completely outside the repaint area.
     209           0 :     if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
     210           0 :         || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
     211           0 :         || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
     212           0 :         || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
     213             :     {
     214           0 :         return;
     215             :     }
     216           0 :     ProvideTheme(rxCanvas);
     217             : 
     218           0 :     if (mpRenderer.get() != NULL)
     219             :     {
     220           0 :         mpRenderer->SetCanvas(rxCanvas);
     221             :         mpRenderer->SetupClipping(
     222             :             rRepaintArea,
     223             :             rOuterBorderRectangle,
     224           0 :             rsPaneBorderStyleName);
     225             :         mpRenderer->PaintBorder(
     226             :             rsTitle,
     227             :             rOuterBorderRectangle,
     228             :             rRepaintArea,
     229           0 :             rsPaneBorderStyleName);
     230             :     }
     231             : }
     232             : 
     233           0 : void SAL_CALL PresenterPaneBorderPainter::paintBorderWithCallout (
     234             :     const OUString& rsPaneBorderStyleName,
     235             :     const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
     236             :     const css::awt::Rectangle& rOuterBorderRectangle,
     237             :     const css::awt::Rectangle& rRepaintArea,
     238             :     const OUString& rsTitle,
     239             :     const css::awt::Point& rCalloutAnchor)
     240             :     throw(css::uno::RuntimeException, std::exception)
     241             : {
     242           0 :     ThrowIfDisposed();
     243             : 
     244             :     // Early reject paints completely outside the repaint area.
     245           0 :     if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
     246           0 :         || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
     247           0 :         || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
     248           0 :         || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
     249             :     {
     250           0 :         return;
     251             :     }
     252           0 :     ProvideTheme(rxCanvas);
     253             : 
     254           0 :     if (mpRenderer.get() != NULL)
     255             :     {
     256           0 :         mpRenderer->SetCanvas(rxCanvas);
     257             :         mpRenderer->SetupClipping(
     258             :             rRepaintArea,
     259             :             rOuterBorderRectangle,
     260           0 :             rsPaneBorderStyleName);
     261           0 :         mpRenderer->SetCalloutAnchor(rCalloutAnchor);
     262             :         mpRenderer->PaintBorder(
     263             :             rsTitle,
     264             :             rOuterBorderRectangle,
     265             :             rRepaintArea,
     266           0 :             rsPaneBorderStyleName);
     267             :     }
     268             : }
     269             : 
     270           0 : awt::Point SAL_CALL PresenterPaneBorderPainter::getCalloutOffset (
     271             :     const OUString& rsPaneBorderStyleName)
     272             :     throw(css::uno::RuntimeException, std::exception)
     273             : {
     274           0 :     ThrowIfDisposed();
     275           0 :     ProvideTheme();
     276           0 :     if (mpRenderer.get() != NULL)
     277             :     {
     278             :         const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(
     279           0 :             mpRenderer->GetRendererPaneStyle(rsPaneBorderStyleName));
     280           0 :         if (pRendererPaneStyle.get() != NULL
     281           0 :             && pRendererPaneStyle->mpBottomCallout.get() != NULL)
     282             :         {
     283             :             return awt::Point (
     284             :                 0,
     285           0 :                 pRendererPaneStyle->mpBottomCallout->mnHeight
     286           0 :                     - pRendererPaneStyle->mpBottomCallout->mnYHotSpot);
     287           0 :         }
     288             :     }
     289             : 
     290           0 :     return awt::Point(0,0);
     291             : }
     292             : 
     293             : 
     294             : 
     295           0 : bool PresenterPaneBorderPainter::ProvideTheme (const Reference<rendering::XCanvas>& rxCanvas)
     296             : {
     297           0 :     bool bModified (false);
     298             : 
     299           0 :     if ( ! mxContext.is())
     300           0 :         return false;
     301             : 
     302           0 :     if (mpTheme.get() != NULL)
     303             :     {
     304             :         // Check if the theme already has a canvas.
     305           0 :         if ( ! mpTheme->HasCanvas())
     306             :         {
     307           0 :             mpTheme->ProvideCanvas(rxCanvas);
     308           0 :             bModified = true;
     309             :         }
     310             :     }
     311             :     else
     312             :     {
     313           0 :         mpTheme.reset(new PresenterTheme(mxContext, OUString(), rxCanvas));
     314           0 :         bModified = true;
     315             :     }
     316             : 
     317           0 :     if (mpTheme.get() != NULL && bModified)
     318             :     {
     319           0 :         if (mpRenderer.get() == NULL)
     320           0 :             mpRenderer.reset(new Renderer(mxContext, mpTheme));
     321             :         else
     322           0 :             mpRenderer->SetCanvas(rxCanvas);
     323             :     }
     324             : 
     325           0 :     return bModified;
     326             : }
     327             : 
     328           0 : bool PresenterPaneBorderPainter::ProvideTheme()
     329             : {
     330           0 :     if (mpTheme.get() == NULL)
     331             :     {
     332             :         // Create a theme without bitmaps (no canvas => no bitmaps).
     333           0 :         return ProvideTheme(NULL);
     334             :     }
     335             :     else
     336             :     {
     337             :         // When there already is a theme then without a canvas we can not
     338             :         // add anything new.
     339           0 :         return false;
     340             :     }
     341             : }
     342             : 
     343           0 : void PresenterPaneBorderPainter::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
     344             : {
     345           0 :     mpTheme = rpTheme;
     346           0 :     if (mpRenderer.get() == NULL)
     347           0 :         mpRenderer.reset(new Renderer(mxContext, mpTheme));
     348           0 : }
     349             : 
     350           0 : awt::Rectangle PresenterPaneBorderPainter::AddBorder (
     351             :     const OUString& rsPaneURL,
     352             :     const awt::Rectangle& rInnerBox,
     353             :     const css::drawing::framework::BorderType eBorderType) const
     354             : {
     355           0 :     if (mpRenderer.get() != NULL)
     356             :     {
     357           0 :         const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
     358           0 :         if (pRendererPaneStyle.get() != NULL)
     359           0 :             return pRendererPaneStyle->AddBorder(rInnerBox, eBorderType);
     360             :     }
     361           0 :     return rInnerBox;
     362             : }
     363             : 
     364           0 : awt::Rectangle PresenterPaneBorderPainter::RemoveBorder (
     365             :     const OUString& rsPaneURL,
     366             :     const css::awt::Rectangle& rOuterBox,
     367             :     const css::drawing::framework::BorderType eBorderType) const
     368             : {
     369           0 :     if (mpRenderer.get() != NULL)
     370             :     {
     371           0 :         const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
     372           0 :         if (pRendererPaneStyle.get() != NULL)
     373           0 :             return pRendererPaneStyle->RemoveBorder(rOuterBox, eBorderType);
     374             :     }
     375           0 :     return rOuterBox;
     376             : }
     377             : 
     378           0 : void PresenterPaneBorderPainter::ThrowIfDisposed() const
     379             :     throw (::com::sun::star::lang::DisposedException)
     380             : {
     381           0 :     if (rBHelper.bDisposed || rBHelper.bInDispose)
     382             :     {
     383             :         throw lang::DisposedException (
     384             :             OUString(
     385             :                 "PresenterPaneBorderPainter object has already been disposed"),
     386           0 :             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
     387             :     }
     388           0 : }
     389             : 
     390             : //===== PresenterPaneBorderPainter::Renderer =====================================
     391             : 
     392           0 : PresenterPaneBorderPainter::Renderer::Renderer (
     393             :     const Reference<XComponentContext>& rxContext,
     394             :     const ::boost::shared_ptr<PresenterTheme>& rpTheme)
     395             :     : mpTheme(rpTheme),
     396             :       maRendererPaneStyles(),
     397             :       mxCanvas(),
     398             :       mxPresenterHelper(),
     399             :       maViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
     400             :       mxViewStateClip(),
     401             :       mbHasCallout(false),
     402           0 :       maCalloutAnchor()
     403             : {
     404             :     (void)rxContext;
     405             : 
     406           0 :     Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
     407           0 :     if (xFactory.is())
     408             :     {
     409           0 :         mxPresenterHelper = Reference<drawing::XPresenterHelper>(
     410           0 :             xFactory->createInstanceWithContext(
     411             :                 OUString("com.sun.star.comp.Draw.PresenterHelper"),
     412           0 :                 rxContext),
     413           0 :             UNO_QUERY_THROW);
     414           0 :     }
     415           0 : }
     416             : 
     417           0 : PresenterPaneBorderPainter::Renderer::~Renderer()
     418             : {
     419           0 : }
     420             : 
     421           0 : void PresenterPaneBorderPainter::Renderer::SetCanvas (const Reference<rendering::XCanvas>& rxCanvas)
     422             : {
     423           0 :     if (mxCanvas != rxCanvas)
     424             :     {
     425           0 :         mxCanvas = rxCanvas;
     426             :     }
     427           0 : }
     428             : 
     429           0 : void PresenterPaneBorderPainter::Renderer::PaintBorder (
     430             :     const OUString& rsTitle,
     431             :     const awt::Rectangle& rBBox,
     432             :     const awt::Rectangle& rUpdateBox,
     433             :     const OUString& rsPaneURL)
     434             : {
     435           0 :     if ( ! mxCanvas.is())
     436           0 :         return;
     437             : 
     438             :     // Create the outer and inner border of the, ahm, border.
     439           0 :     ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneURL));
     440           0 :     if (pStyle.get() == NULL)
     441           0 :         return;
     442             : 
     443           0 :     awt::Rectangle aOuterBox (rBBox);
     444             :     awt::Rectangle aCenterBox (
     445           0 :         pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_OUTER_BORDER));
     446             :     awt::Rectangle aInnerBox (
     447           0 :         pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
     448             : 
     449             :     // Prepare references for all used bitmaps.
     450           0 :     SharedBitmapDescriptor pTop (pStyle->mpTop);
     451           0 :     SharedBitmapDescriptor pTopLeft (pStyle->mpTopLeft);
     452           0 :     SharedBitmapDescriptor pTopRight (pStyle->mpTopRight);
     453           0 :     SharedBitmapDescriptor pLeft (pStyle->mpLeft);
     454           0 :     SharedBitmapDescriptor pRight (pStyle->mpRight);
     455           0 :     SharedBitmapDescriptor pBottomLeft (pStyle->mpBottomLeft);
     456           0 :     SharedBitmapDescriptor pBottomRight (pStyle->mpBottomRight);
     457           0 :     SharedBitmapDescriptor pBottom (pStyle->mpBottom);
     458           0 :     SharedBitmapDescriptor pBackground (pStyle->mpBackground);
     459             : 
     460             :     // Paint the sides.
     461             :     PaintBitmap(aCenterBox, rUpdateBox, 0,-1,
     462           0 :         pTopLeft->mnXOffset, pTopRight->mnXOffset, true, pTop, pBackground);
     463             :     PaintBitmap(aCenterBox, rUpdateBox, -1,0,
     464           0 :         pTopLeft->mnYOffset, pBottomLeft->mnYOffset, true, pLeft, pBackground);
     465             :     PaintBitmap(aCenterBox, rUpdateBox, +1,0,
     466           0 :         pTopRight->mnYOffset, pBottomRight->mnYOffset, true, pRight, pBackground);
     467           0 :     if (mbHasCallout && pStyle->mpBottomCallout->GetNormalBitmap().is())
     468             :     {
     469           0 :         const sal_Int32 nCalloutWidth (pStyle->mpBottomCallout->mnWidth);
     470           0 :         sal_Int32 nCalloutX (maCalloutAnchor.X - pStyle->mpBottomCallout->mnXHotSpot
     471           0 :             - (aCenterBox.X - aOuterBox.X));
     472           0 :         if (nCalloutX < pBottomLeft->mnXOffset + aCenterBox.X)
     473           0 :             nCalloutX = pBottomLeft->mnXOffset + aCenterBox.X;
     474           0 :         if (nCalloutX > pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width)
     475           0 :             nCalloutX = pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width;
     476             :         // Paint bottom callout.
     477           0 :         PaintBitmap(aCenterBox, rUpdateBox, 0,+1, nCalloutX,0, false, pStyle->mpBottomCallout, pBackground);
     478             :         // Paint regular bottom bitmap left and right.
     479             :         PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
     480           0 :             pBottomLeft->mnXOffset, nCalloutX-aCenterBox.Width, true, pBottom, pBackground);
     481             :         PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
     482           0 :             nCalloutX+nCalloutWidth, pBottomRight->mnXOffset, true, pBottom, pBackground);
     483             :     }
     484             :     else
     485             :     {
     486             :         // Stretch the bottom bitmap over the full width.
     487             :         PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
     488           0 :             pBottomLeft->mnXOffset, pBottomRight->mnXOffset, true, pBottom, pBackground);
     489             :     }
     490             : 
     491             :     // Paint the corners.
     492           0 :     PaintBitmap(aCenterBox, rUpdateBox, -1,-1, 0,0, false, pTopLeft, pBackground);
     493           0 :     PaintBitmap(aCenterBox, rUpdateBox, +1,-1, 0,0, false, pTopRight, pBackground);
     494           0 :     PaintBitmap(aCenterBox, rUpdateBox, -1,+1, 0,0, false, pBottomLeft, pBackground);
     495           0 :     PaintBitmap(aCenterBox, rUpdateBox, +1,+1, 0,0, false, pBottomRight, pBackground);
     496             : 
     497             :     // Paint the title.
     498           0 :     PaintTitle(rsTitle, pStyle, rUpdateBox, aOuterBox, aInnerBox, false);
     499             : 
     500             :     // In a double buffering environment request to make the changes visible.
     501           0 :     Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
     502           0 :     if (xSpriteCanvas.is())
     503           0 :         xSpriteCanvas->updateScreen(sal_False);
     504             : }
     505             : 
     506           0 : void PresenterPaneBorderPainter::Renderer::PaintTitle (
     507             :     const OUString& rsTitle,
     508             :     const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
     509             :     const awt::Rectangle& rUpdateBox,
     510             :     const awt::Rectangle& rOuterBox,
     511             :     const awt::Rectangle& rInnerBox,
     512             :     bool bPaintBackground)
     513             : {
     514           0 :     if ( ! mxCanvas.is())
     515           0 :         return;
     516             : 
     517           0 :     if (rsTitle.isEmpty())
     518           0 :         return;
     519             : 
     520           0 :     Reference<rendering::XCanvasFont> xFont (rpStyle->GetFont(mxCanvas));
     521           0 :     if ( ! xFont.is())
     522           0 :         return;
     523             : 
     524             :     rendering::StringContext aContext (
     525             :         rsTitle,
     526             :         0,
     527           0 :         rsTitle.getLength());
     528           0 :     Reference<rendering::XTextLayout> xLayout (xFont->createTextLayout(
     529             :         aContext,
     530             :         rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
     531           0 :         0));
     532           0 :     if ( ! xLayout.is())
     533           0 :         return;
     534             : 
     535             :     /// this is responsible of the texts above the slide windows
     536           0 :     geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
     537           0 :     const double nTextHeight = aBox.Y2 - aBox.Y1;
     538           0 :     const double nTextWidth = aBox.X1 + aBox.X2;
     539           0 :     double nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
     540           0 :     const sal_Int32 nTitleBarHeight = rInnerBox.Y - rOuterBox.Y - 1;
     541           0 :     double nY = rOuterBox.Y + (nTitleBarHeight - nTextHeight) / 2 - aBox.Y1;
     542           0 :     if (nY >= rInnerBox.Y)
     543           0 :         nY = rInnerBox.Y - 1;
     544           0 :     switch (rpStyle->meFontAnchor)
     545             :     {
     546             :         default:
     547             :         case RendererPaneStyle::AnchorLeft:
     548           0 :         nX = rInnerBox.X;
     549           0 :         break;
     550             :         case RendererPaneStyle::AnchorRight:
     551           0 :         nX = rInnerBox.X + rInnerBox.Width - nTextWidth;
     552           0 :         break;
     553             :         case RendererPaneStyle::AnchorCenter:
     554           0 :         nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
     555           0 :         break;
     556             :     }
     557           0 :     nX += rpStyle->mnFontXOffset;
     558           0 :     nY += rpStyle->mnFontYOffset;
     559             : 
     560           0 :     if (rUpdateBox.X >= nX+nTextWidth
     561           0 :         || rUpdateBox.Y >= nY+nTextHeight
     562           0 :         || rUpdateBox.X+rUpdateBox.Width <= nX
     563           0 :         || rUpdateBox.Y+rUpdateBox.Height <= nY)
     564             :     {
     565           0 :         return;
     566             :     }
     567             : 
     568             :     rendering::RenderState aRenderState(
     569             :         geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
     570             :         NULL,
     571             :         Sequence<double>(4),
     572           0 :         rendering::CompositeOperation::SOURCE);
     573             : 
     574           0 :     if (bPaintBackground)
     575             :     {
     576           0 :         PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
     577           0 :         Sequence<Sequence<geometry::RealPoint2D> > aPolygons(1);
     578           0 :         aPolygons[0] = Sequence<geometry::RealPoint2D>(4);
     579           0 :         aPolygons[0][0] = geometry::RealPoint2D(0, -nTextHeight);
     580           0 :         aPolygons[0][1] = geometry::RealPoint2D(0, 0);
     581           0 :         aPolygons[0][2] = geometry::RealPoint2D(nTextWidth, 0);
     582           0 :         aPolygons[0][3] = geometry::RealPoint2D(nTextWidth, -nTextHeight);
     583             :         Reference<rendering::XPolyPolygon2D> xPolygon (
     584           0 :         mxCanvas->getDevice()->createCompatibleLinePolyPolygon(aPolygons), UNO_QUERY);
     585           0 :         if (xPolygon.is())
     586           0 :             xPolygon->setClosed(0, sal_True);
     587           0 :         mxCanvas->fillPolyPolygon(
     588             :             xPolygon,
     589             :             maViewState,
     590           0 :             aRenderState);
     591             :     }
     592             :     else
     593             :     {
     594             :         PresenterCanvasHelper::SetDeviceColor(
     595             :             aRenderState,
     596           0 :             rpStyle->mpFont->mnColor);
     597             : 
     598           0 :         mxCanvas->drawTextLayout (
     599             :             xLayout,
     600             :             maViewState,
     601           0 :             aRenderState);
     602           0 :     }
     603             : }
     604             : 
     605             : ::boost::shared_ptr<RendererPaneStyle>
     606           0 :     PresenterPaneBorderPainter::Renderer::GetRendererPaneStyle (const OUString& rsResourceURL)
     607             : {
     608             :     OSL_ASSERT(mpTheme.get()!=NULL);
     609             : 
     610           0 :     RendererPaneStyleContainer::const_iterator iStyle (maRendererPaneStyles.find(rsResourceURL));
     611           0 :     if (iStyle == maRendererPaneStyles.end())
     612             :     {
     613           0 :         OUString sPaneStyleName ("DefaultRendererPaneStyle");
     614             : 
     615             :         // Get pane layout name for resource URL.
     616           0 :         const OUString sStyleName (mpTheme->GetStyleName(rsResourceURL));
     617           0 :         if (!sStyleName.isEmpty())
     618           0 :             sPaneStyleName = sStyleName;
     619             : 
     620             :         // Create a new pane style object and initialize it with bitmaps.
     621             :         ::boost::shared_ptr<RendererPaneStyle> pStyle (
     622           0 :             new RendererPaneStyle(mpTheme,sPaneStyleName));
     623             :         iStyle = maRendererPaneStyles.insert(
     624           0 :             RendererPaneStyleContainer::value_type(rsResourceURL, pStyle)).first;
     625             :     }
     626           0 :     if (iStyle != maRendererPaneStyles.end())
     627           0 :         return iStyle->second;
     628             :     else
     629           0 :         return ::boost::shared_ptr<RendererPaneStyle>();
     630             : }
     631             : 
     632           0 : void PresenterPaneBorderPainter::Renderer::SetCalloutAnchor (
     633             :     const awt::Point& rCalloutAnchor)
     634             : {
     635           0 :     mbHasCallout = true;
     636           0 :     maCalloutAnchor = rCalloutAnchor;
     637           0 : }
     638             : 
     639           0 : void PresenterPaneBorderPainter::Renderer::PaintBitmap(
     640             :     const awt::Rectangle& rBox,
     641             :     const awt::Rectangle& rUpdateBox,
     642             :     const sal_Int32 nXPosition,
     643             :     const sal_Int32 nYPosition,
     644             :     const sal_Int32 nStartOffset,
     645             :     const sal_Int32 nEndOffset,
     646             :     const bool bExpand,
     647             :     const SharedBitmapDescriptor& rpBitmap,
     648             :     const SharedBitmapDescriptor& rpBackgroundBitmap)
     649             : {
     650             :     (void)rpBackgroundBitmap;
     651             : 
     652           0 :     bool bUseCanvas (mxCanvas.is());
     653           0 :     if ( ! bUseCanvas)
     654           0 :         return;
     655             : 
     656           0 :     if (rpBitmap->mnWidth<=0 || rpBitmap->mnHeight<=0)
     657           0 :         return;
     658             : 
     659           0 :     Reference<rendering::XBitmap> xBitmap (rpBitmap->GetNormalBitmap(), UNO_QUERY);
     660           0 :     if ( ! xBitmap.is())
     661           0 :         return;
     662             : 
     663             :     // Calculate position, and for side bitmaps, the size.
     664           0 :     sal_Int32 nX = 0;
     665           0 :     sal_Int32 nY = 0;
     666           0 :     sal_Int32 nW = rpBitmap->mnWidth;
     667           0 :     sal_Int32 nH = rpBitmap->mnHeight;
     668           0 :     if (nXPosition < 0)
     669             :     {
     670           0 :         nX = rBox.X - rpBitmap->mnWidth + rpBitmap->mnXOffset;
     671             :     }
     672           0 :     else if (nXPosition > 0)
     673             :     {
     674           0 :         nX = rBox.X + rBox.Width + rpBitmap->mnXOffset;
     675             :     }
     676             :     else
     677             :     {
     678           0 :         nX = rBox.X + nStartOffset;
     679           0 :         if (bExpand)
     680           0 :             nW = rBox.Width - nStartOffset + nEndOffset;
     681             :     }
     682             : 
     683           0 :     if (nYPosition < 0)
     684             :     {
     685           0 :         nY = rBox.Y - rpBitmap->mnHeight + rpBitmap->mnYOffset;
     686             :     }
     687           0 :     else if (nYPosition > 0)
     688             :     {
     689           0 :         nY = rBox.Y + rBox.Height + rpBitmap->mnYOffset;
     690             :     }
     691             :     else
     692             :     {
     693           0 :         nY = rBox.Y + nStartOffset;
     694           0 :         if (bExpand)
     695           0 :             nH = rBox.Height - nStartOffset + nEndOffset;
     696             :     }
     697             : 
     698             :     // Do not paint when bitmap area does not intersect with update box.
     699           0 :     if (nX >= rUpdateBox.X + rUpdateBox.Width
     700           0 :         || nX+nW <= rUpdateBox.X
     701           0 :         || nY >= rUpdateBox.Y + rUpdateBox.Height
     702           0 :         || nY+nH <= rUpdateBox.Y)
     703             :     {
     704           0 :         return;
     705             :     }
     706             : 
     707             :     /*
     708             :     Reference<rendering::XBitmap> xMaskedBitmap (
     709             :         PresenterBitmapHelper::FillMaskedWithColor (
     710             :             mxCanvas,
     711             :             Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
     712             :             rBitmap.mxMaskBitmap,
     713             :             0x00ff0000,
     714             :             rBackgroundBitmap.maReplacementColor));
     715             :     if (xMaskedBitmap.is())
     716             :         xBitmap = xMaskedBitmap;
     717             :     else if (rBitmap.mxMaskBitmap.is() && mxPresenterHelper.is())
     718             :     {
     719             :         const static sal_Int32 nOutsideMaskColor (0x00ff0000);
     720             :         Reference<rendering::XIntegerBitmap> xMask (
     721             :             mxPresenterHelper->createMask(
     722             :                 mxCanvas,
     723             :                 rBitmap.mxMaskBitmap,
     724             :                 nOutsideMaskColor,
     725             :                 false));
     726             :         xBitmap = mxPresenterHelper->applyBitmapMaskWithColor(
     727             :             mxCanvas,
     728             :             Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
     729             :             xMask,
     730             :             rBackgroundBitmap.maReplacementColor);
     731             :     }
     732             :     */
     733             :     rendering::RenderState aRenderState (
     734             :         geometry::AffineMatrix2D(
     735           0 :             double(nW)/rpBitmap->mnWidth, 0, nX,
     736           0 :             0, double(nH)/rpBitmap->mnHeight, nY),
     737             :         NULL,
     738             :         Sequence<double>(4),
     739           0 :         rendering::CompositeOperation::OVER);
     740             : 
     741           0 :     if (xBitmap.is())
     742           0 :         mxCanvas->drawBitmap(
     743             :             xBitmap,
     744             :             maViewState,
     745           0 :             aRenderState);
     746             : }
     747             : 
     748           0 : void PresenterPaneBorderPainter::Renderer::SetupClipping (
     749             :     const awt::Rectangle& rUpdateBox,
     750             :     const awt::Rectangle& rOuterBox,
     751             :     const OUString& rsPaneStyleName)
     752             : {
     753           0 :     mxViewStateClip = NULL;
     754           0 :     maViewState.Clip = NULL;
     755             : 
     756           0 :     if ( ! mxCanvas.is())
     757           0 :         return;
     758             : 
     759           0 :     ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneStyleName));
     760           0 :     if (pStyle.get() == NULL)
     761             :     {
     762           0 :         mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
     763             :             rUpdateBox,
     764           0 :             mxCanvas->getDevice());
     765             :     }
     766             :     else
     767             :     {
     768             :         awt::Rectangle aInnerBox (
     769           0 :             pStyle->RemoveBorder(rOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
     770           0 :         ::std::vector<awt::Rectangle> aRectangles;
     771           0 :         aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, rOuterBox));
     772           0 :         aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, aInnerBox));
     773           0 :         mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
     774             :             aRectangles,
     775           0 :             mxCanvas->getDevice());
     776           0 :         if (mxViewStateClip.is())
     777           0 :             mxViewStateClip->setFillRule(rendering::FillRule_EVEN_ODD);
     778             :     }
     779           0 :     maViewState.Clip = mxViewStateClip;
     780             : }
     781             : 
     782             : namespace {
     783             : 
     784             : //===== BorderSize ============================================================
     785             : 
     786           0 : BorderSize::BorderSize()
     787             :     : mnLeft(0),
     788             :       mnTop(0),
     789             :       mnRight(0),
     790           0 :       mnBottom(0)
     791             : {
     792           0 : }
     793             : 
     794             : //===== RendererPaneStyle  ============================================================
     795             : 
     796           0 : RendererPaneStyle::RendererPaneStyle (
     797             :     const ::boost::shared_ptr<PresenterTheme>& rpTheme,
     798             :     const OUString& rsStyleName)
     799             :     : mpTopLeft(),
     800             :       mpTop(),
     801             :       mpTopRight(),
     802             :       mpLeft(),
     803             :       mpRight(),
     804             :       mpBottomLeft(),
     805             :       mpBottom(),
     806             :       mpBottomRight(),
     807             :       mpBottomCallout(),
     808             :       mpBackground(),
     809           0 :       mpEmpty(new PresenterBitmapDescriptor()),
     810             :       mpFont(),
     811             :       mnFontXOffset(0),
     812             :       mnFontYOffset(0),
     813             :       meFontAnchor(AnchorCenter),
     814             :       maInnerBorderSize(),
     815             :       maOuterBorderSize(),
     816           0 :       maTotalBorderSize()
     817             : {
     818           0 :     if (rpTheme.get() != NULL)
     819             :     {
     820           0 :         mpTopLeft = GetBitmap(rpTheme, rsStyleName, "TopLeft");
     821           0 :         mpTop = GetBitmap(rpTheme, rsStyleName, "Top");
     822           0 :         mpTopRight = GetBitmap(rpTheme, rsStyleName, "TopRight");
     823           0 :         mpLeft = GetBitmap(rpTheme, rsStyleName,"Left");
     824           0 :         mpRight = GetBitmap(rpTheme, rsStyleName, "Right");
     825           0 :         mpBottomLeft = GetBitmap(rpTheme, rsStyleName, "BottomLeft");
     826           0 :         mpBottom = GetBitmap(rpTheme, rsStyleName, "Bottom");
     827           0 :         mpBottomRight = GetBitmap(rpTheme, rsStyleName, "BottomRight");
     828           0 :         mpBottomCallout = GetBitmap(rpTheme, rsStyleName, "BottomCallout");
     829           0 :         mpBackground = GetBitmap(rpTheme, OUString(), "Background");
     830             : 
     831             :         // Get font description.
     832           0 :         mpFont = rpTheme->GetFont(rsStyleName);
     833             : 
     834           0 :         OUString sAnchor ("Left");
     835           0 :         if (mpFont.get() != NULL)
     836             :         {
     837           0 :             sAnchor = mpFont->msAnchor;
     838           0 :             mnFontXOffset = mpFont->mnXOffset;
     839           0 :             mnFontYOffset = mpFont->mnYOffset;
     840             :         }
     841             : 
     842           0 :         if ( sAnchor == "Left" )
     843           0 :             meFontAnchor = AnchorLeft;
     844           0 :         else if ( sAnchor == "Right" )
     845           0 :             meFontAnchor = AnchorRight;
     846             :         else
     847           0 :             meFontAnchor = AnchorCenter;
     848             : 
     849             :         // Get border sizes.
     850             :         try
     851             :         {
     852           0 :             ::std::vector<sal_Int32> aInnerBorder (rpTheme->GetBorderSize(rsStyleName, false));
     853             :             OSL_ASSERT(aInnerBorder.size()==4);
     854           0 :             maInnerBorderSize.mnLeft = aInnerBorder[0];
     855           0 :             maInnerBorderSize.mnTop = aInnerBorder[1];
     856           0 :             maInnerBorderSize.mnRight = aInnerBorder[2];
     857           0 :             maInnerBorderSize.mnBottom = aInnerBorder[3];
     858             : 
     859           0 :             ::std::vector<sal_Int32> aOuterBorder (rpTheme->GetBorderSize(rsStyleName, true));
     860             :             OSL_ASSERT(aOuterBorder.size()==4);
     861           0 :             maOuterBorderSize.mnLeft = aOuterBorder[0];
     862           0 :             maOuterBorderSize.mnTop = aOuterBorder[1];
     863           0 :             maOuterBorderSize.mnRight = aOuterBorder[2];
     864           0 :             maOuterBorderSize.mnBottom = aOuterBorder[3];
     865             :         }
     866           0 :         catch(beans::UnknownPropertyException&)
     867             :         {
     868             :             OSL_ASSERT(false);
     869             :         }
     870             : 
     871           0 :         UpdateBorderSizes();
     872             :     }
     873           0 : }
     874             : 
     875           0 : awt::Rectangle RendererPaneStyle::AddBorder (
     876             :     const awt::Rectangle& rBox,
     877             :     const drawing::framework::BorderType eBorderType) const
     878             : {
     879           0 :     const BorderSize* pBorderSize = NULL;
     880           0 :     switch (eBorderType)
     881             :     {
     882             :         case drawing::framework::BorderType_INNER_BORDER:
     883           0 :             pBorderSize = &maInnerBorderSize;
     884           0 :             break;
     885             :         case drawing::framework::BorderType_OUTER_BORDER:
     886           0 :             pBorderSize = &maOuterBorderSize;
     887           0 :             break;
     888             :         case drawing::framework::BorderType_TOTAL_BORDER:
     889           0 :             pBorderSize = &maTotalBorderSize;
     890           0 :             break;
     891             :         default:
     892           0 :             return rBox;
     893             :     }
     894             :     return awt::Rectangle (
     895           0 :         rBox.X - pBorderSize->mnLeft,
     896           0 :         rBox.Y - pBorderSize->mnTop,
     897           0 :         rBox.Width + pBorderSize->mnLeft + pBorderSize->mnRight,
     898           0 :         rBox.Height + pBorderSize->mnTop + pBorderSize->mnBottom);
     899             : }
     900             : 
     901           0 : awt::Rectangle RendererPaneStyle::RemoveBorder (
     902             :     const awt::Rectangle& rBox,
     903             :     const css::drawing::framework::BorderType eBorderType) const
     904             : {
     905           0 :     const BorderSize* pBorderSize = NULL;
     906           0 :     switch (eBorderType)
     907             :     {
     908             :         case drawing::framework::BorderType_INNER_BORDER:
     909           0 :             pBorderSize = &maInnerBorderSize;
     910           0 :             break;
     911             :         case drawing::framework::BorderType_OUTER_BORDER:
     912           0 :             pBorderSize = &maOuterBorderSize;
     913           0 :             break;
     914             :         case drawing::framework::BorderType_TOTAL_BORDER:
     915           0 :             pBorderSize = &maTotalBorderSize;
     916           0 :             break;
     917             :         default:
     918           0 :             return rBox;
     919             :     }
     920             :     return awt::Rectangle (
     921           0 :         rBox.X + pBorderSize->mnLeft,
     922           0 :         rBox.Y + pBorderSize->mnTop,
     923           0 :         rBox.Width - pBorderSize->mnLeft - pBorderSize->mnRight,
     924           0 :         rBox.Height - pBorderSize->mnTop - pBorderSize->mnBottom);
     925             : }
     926             : 
     927           0 : const Reference<rendering::XCanvasFont> RendererPaneStyle::GetFont (
     928             :     const Reference<rendering::XCanvas>& rxCanvas) const
     929             : {
     930           0 :     if (mpFont.get() != NULL)
     931           0 :         mpFont->PrepareFont(rxCanvas);
     932           0 :     return mpFont->mxFont;
     933             : }
     934             : 
     935           0 : void RendererPaneStyle::UpdateBorderSizes()
     936             : {
     937           0 :     maTotalBorderSize.mnLeft = maInnerBorderSize.mnLeft + maOuterBorderSize.mnLeft;
     938           0 :     maTotalBorderSize.mnTop = maInnerBorderSize.mnTop + maOuterBorderSize.mnTop;
     939           0 :     maTotalBorderSize.mnRight = maInnerBorderSize.mnRight + maOuterBorderSize.mnRight;
     940           0 :     maTotalBorderSize.mnBottom = maInnerBorderSize.mnBottom + maOuterBorderSize.mnBottom;
     941           0 : }
     942             : 
     943           0 : SharedBitmapDescriptor RendererPaneStyle::GetBitmap(
     944             :     const ::boost::shared_ptr<PresenterTheme>& rpTheme,
     945             :     const OUString& rsStyleName,
     946             :     const OUString& rsBitmapName)
     947             : {
     948           0 :     SharedBitmapDescriptor pDescriptor (rpTheme->GetBitmap(rsStyleName, rsBitmapName));
     949           0 :     if (pDescriptor.get() != NULL)
     950           0 :         return pDescriptor;
     951             :     else
     952           0 :         return mpEmpty;
     953             : }
     954             : 
     955             : } // end of anonymous namespace
     956             : 
     957             : } } // end of namespace ::sd::presenter
     958             : 
     959             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11