LCOV - code coverage report
Current view: top level - sdext/source/presenter - PresenterHelpView.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 1 311 0.3 %
Date: 2014-04-11 Functions: 2 40 5.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             : #include "vcl/svapp.hxx"
      20             : #include "vcl/settings.hxx"
      21             : #include "PresenterHelpView.hxx"
      22             : #include "PresenterButton.hxx"
      23             : #include "PresenterCanvasHelper.hxx"
      24             : #include "PresenterGeometryHelper.hxx"
      25             : #include "PresenterHelper.hxx"
      26             : #include "PresenterWindowManager.hxx"
      27             : #include <com/sun/star/awt/XWindowPeer.hpp>
      28             : #include <com/sun/star/container/XNameAccess.hpp>
      29             : #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
      30             : #include <com/sun/star/drawing/framework/XControllerManager.hpp>
      31             : #include <com/sun/star/rendering/CompositeOperation.hpp>
      32             : #include <com/sun/star/rendering/TextDirection.hpp>
      33             : #include <com/sun/star/util/Color.hpp>
      34             : #include <algorithm>
      35             : #include <vector>
      36             : #include <boost/bind.hpp>
      37             : 
      38             : using namespace ::com::sun::star;
      39             : using namespace ::com::sun::star::uno;
      40             : using namespace ::com::sun::star::drawing::framework;
      41             : using ::std::vector;
      42             : 
      43             : namespace sdext { namespace presenter {
      44             : 
      45             : namespace {
      46             :     const static sal_Int32 gnHorizontalGap (20);
      47             :     const static sal_Int32 gnVerticalBorder (30);
      48             :     const static sal_Int32 gnVerticalButtonPadding (12);
      49             : 
      50           0 :     class LineDescriptor
      51             :     {
      52             :     public:
      53             :         LineDescriptor(void);
      54             :         void AddPart (
      55             :             const OUString& rsLine,
      56             :             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
      57             :         bool IsEmpty (void) const;
      58             : 
      59             :         OUString msLine;
      60             :         geometry::RealSize2D maSize;
      61             :         double mnVerticalOffset;
      62             : 
      63             :         void CalculateSize (const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
      64             :     };
      65             : 
      66           0 :     class LineDescriptorList
      67             :     {
      68             :     public:
      69             :         LineDescriptorList (
      70             :             const OUString& rsText,
      71             :             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
      72             :             const sal_Int32 nMaximalWidth);
      73             : 
      74             :         void Update (
      75             :             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
      76             :             const sal_Int32 nMaximalWidth);
      77             : 
      78             :         double Paint(
      79             :             const Reference<rendering::XCanvas>& rxCanvas,
      80             :             const geometry::RealRectangle2D& rBBox,
      81             :             const bool bFlushLeft,
      82             :             const rendering::ViewState& rViewState,
      83             :             rendering::RenderState& rRenderState,
      84             :             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const;
      85             :         double GetHeight (void) const;
      86             : 
      87             :     private:
      88             :         const OUString msText;
      89             :         ::boost::shared_ptr<vector<LineDescriptor> > mpLineDescriptors;
      90             : 
      91             :         void SplitText (const OUString& rsText, vector<OUString>& rTextParts);
      92             :         void FormatText (
      93             :             const vector<OUString>& rTextParts,
      94             :             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
      95             :             const sal_Int32 nMaximalWidth);
      96             :     };
      97             : 
      98           0 :     class Block
      99             :     {
     100             :     public:
     101             :         Block (const Block& rBlock);
     102             :         Block (
     103             :             const OUString& rsLeftText,
     104             :             const OUString& rsRightText,
     105             :             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
     106             :             const sal_Int32 nMaximalWidth);
     107             :         void Update (
     108             :             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
     109             :             const sal_Int32 nMaximalWidth);
     110             : 
     111             :         LineDescriptorList maLeft;
     112             :         LineDescriptorList maRight;
     113             :     };
     114             : } // end of anonymous namespace
     115             : 
     116           0 : class PresenterHelpView::TextContainer : public vector<boost::shared_ptr<Block> >
     117             : {
     118             : };
     119             : 
     120           0 : PresenterHelpView::PresenterHelpView (
     121             :     const Reference<uno::XComponentContext>& rxContext,
     122             :     const Reference<XResourceId>& rxViewId,
     123             :     const Reference<frame::XController>& rxController,
     124             :     const ::rtl::Reference<PresenterController>& rpPresenterController)
     125             :     : PresenterHelpViewInterfaceBase(m_aMutex),
     126             :       mxComponentContext(rxContext),
     127             :       mxViewId(rxViewId),
     128             :       mxPane(),
     129             :       mxWindow(),
     130             :       mxCanvas(),
     131             :       mpPresenterController(rpPresenterController),
     132             :       mpFont(),
     133             :       mpTextContainer(),
     134             :       mpCloseButton(),
     135             :       mnSeparatorY(0),
     136           0 :       mnMaximalWidth(0)
     137             : {
     138             :     try
     139             :     {
     140             :         // Get the content window via the pane anchor.
     141           0 :         Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
     142             :         Reference<XConfigurationController> xCC (
     143           0 :             xCM->getConfigurationController(), UNO_QUERY_THROW);
     144           0 :         mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
     145             : 
     146           0 :         mxWindow = mxPane->getWindow();
     147           0 :         ProvideCanvas();
     148             : 
     149           0 :         mxWindow->addWindowListener(this);
     150           0 :         mxWindow->addPaintListener(this);
     151           0 :         Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
     152           0 :         if (xPeer.is())
     153           0 :             xPeer->setBackground(util::Color(0xff000000));
     154           0 :         mxWindow->setVisible(sal_True);
     155             : 
     156           0 :         if (mpPresenterController.is())
     157             :         {
     158           0 :             mpFont = mpPresenterController->GetViewFont(mxViewId->getResourceURL());
     159           0 :             if (mpFont.get() != NULL)
     160             :             {
     161           0 :                 mpFont->PrepareFont(mxCanvas);
     162             :             }
     163             :         }
     164             : 
     165             :         // Create the close button.
     166           0 :         mpCloseButton = PresenterButton::Create(
     167             :             mxComponentContext,
     168             :             mpPresenterController,
     169             :             mpPresenterController->GetTheme(),
     170             :             mxWindow,
     171             :             mxCanvas,
     172           0 :             "HelpViewCloser");
     173             : 
     174           0 :         ReadHelpStrings();
     175           0 :         Resize();
     176             :     }
     177           0 :     catch (RuntimeException&)
     178             :     {
     179           0 :         mxViewId = NULL;
     180           0 :         mxWindow = NULL;
     181           0 :         throw;
     182             :     }
     183           0 : }
     184             : 
     185           0 : PresenterHelpView::~PresenterHelpView (void)
     186             : {
     187           0 : }
     188             : 
     189           0 : void SAL_CALL PresenterHelpView::disposing (void)
     190             : {
     191           0 :     mxViewId = NULL;
     192             : 
     193           0 :     if (mpCloseButton.is())
     194             :     {
     195             :         Reference<lang::XComponent> xComponent (
     196           0 :             static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
     197           0 :         mpCloseButton = NULL;
     198           0 :         if (xComponent.is())
     199           0 :             xComponent->dispose();
     200             :     }
     201             : 
     202           0 :     if (mxWindow.is())
     203             :     {
     204           0 :         mxWindow->removeWindowListener(this);
     205           0 :         mxWindow->removePaintListener(this);
     206             :     }
     207           0 : }
     208             : 
     209             : //----- lang::XEventListener --------------------------------------------------
     210             : 
     211           0 : void SAL_CALL PresenterHelpView::disposing (const lang::EventObject& rEventObject)
     212             :     throw (RuntimeException, std::exception)
     213             : {
     214           0 :     if (rEventObject.Source == mxCanvas)
     215             :     {
     216           0 :         mxCanvas = NULL;
     217             :     }
     218           0 :     else if (rEventObject.Source == mxWindow)
     219             :     {
     220           0 :         mxWindow = NULL;
     221           0 :         dispose();
     222             :     }
     223           0 : }
     224             : 
     225             : //----- XWindowListener -------------------------------------------------------
     226             : 
     227           0 : void SAL_CALL PresenterHelpView::windowResized (const awt::WindowEvent& rEvent)
     228             :     throw (uno::RuntimeException, std::exception)
     229             : {
     230             :     (void)rEvent;
     231           0 :     ThrowIfDisposed();
     232           0 :     Resize();
     233           0 : }
     234             : 
     235           0 : void SAL_CALL PresenterHelpView::windowMoved (const awt::WindowEvent& rEvent)
     236             :     throw (uno::RuntimeException, std::exception)
     237             : {
     238             :     (void)rEvent;
     239           0 :     ThrowIfDisposed();
     240           0 : }
     241             : 
     242           0 : void SAL_CALL PresenterHelpView::windowShown (const lang::EventObject& rEvent)
     243             :     throw (uno::RuntimeException, std::exception)
     244             : {
     245             :     (void)rEvent;
     246           0 :     ThrowIfDisposed();
     247           0 :     Resize();
     248           0 : }
     249             : 
     250           0 : void SAL_CALL PresenterHelpView::windowHidden (const lang::EventObject& rEvent)
     251             :     throw (uno::RuntimeException, std::exception)
     252             : {
     253             :     (void)rEvent;
     254           0 :     ThrowIfDisposed();
     255           0 : }
     256             : 
     257             : //----- XPaintListener --------------------------------------------------------
     258             : 
     259           0 : void SAL_CALL PresenterHelpView::windowPaint (const css::awt::PaintEvent& rEvent)
     260             :     throw (RuntimeException, std::exception)
     261             : {
     262           0 :     Paint(rEvent.UpdateRect);
     263           0 : }
     264             : 
     265           0 : void PresenterHelpView::Paint (const awt::Rectangle& rUpdateBox)
     266             : {
     267           0 :     ProvideCanvas();
     268           0 :     if ( ! mxCanvas.is())
     269           0 :         return;
     270             : 
     271             :     // Clear background.
     272           0 :     const awt::Rectangle aWindowBox (mxWindow->getPosSize());
     273             :     mpPresenterController->GetCanvasHelper()->Paint(
     274           0 :         mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
     275             :         Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY),
     276             :         rUpdateBox,
     277             :         awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
     278           0 :         awt::Rectangle());
     279             : 
     280             :     // Paint vertical divider.
     281             : 
     282             :     rendering::ViewState aViewState(
     283             :         geometry::AffineMatrix2D(1,0,0, 0,1,0),
     284           0 :         PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice()));
     285             : 
     286             :     rendering::RenderState aRenderState (
     287             :         geometry::AffineMatrix2D(1,0,0, 0,1,0),
     288             :         NULL,
     289             :         Sequence<double>(4),
     290           0 :         rendering::CompositeOperation::SOURCE);
     291           0 :     PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
     292             : 
     293           0 :     mxCanvas->drawLine(
     294           0 :         geometry::RealPoint2D(aWindowBox.Width/2, gnVerticalBorder),
     295           0 :         geometry::RealPoint2D(aWindowBox.Width/2, mnSeparatorY - gnVerticalBorder),
     296             :         aViewState,
     297           0 :         aRenderState);
     298             : 
     299             :     // Paint the horizontal separator.
     300           0 :     mxCanvas->drawLine(
     301             :         geometry::RealPoint2D(0, mnSeparatorY),
     302             :         geometry::RealPoint2D(aWindowBox.Width, mnSeparatorY),
     303             :         aViewState,
     304           0 :         aRenderState);
     305             : 
     306             :     // Paint text.
     307           0 :     double nY (gnVerticalBorder);
     308           0 :     TextContainer::const_iterator iBlock (mpTextContainer->begin());
     309           0 :     TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
     310           0 :     for ( ; iBlock!=iBlockEnd; ++iBlock)
     311             :     {
     312           0 :         sal_Int32 LeftX1 = gnHorizontalGap;
     313           0 :         sal_Int32 LeftX2 = aWindowBox.Width/2 - gnHorizontalGap;
     314           0 :         sal_Int32 RightX1 = aWindowBox.Width/2 + gnHorizontalGap;
     315           0 :         sal_Int32 RightX2 = aWindowBox.Width - gnHorizontalGap;
     316             :         /* check whether RTL interface or not
     317             :            then replace the windowbox position */
     318           0 :         if(Application::GetSettings().GetLayoutRTL())
     319             :         {
     320           0 :             LeftX1 = aWindowBox.Width/2 + gnHorizontalGap;
     321           0 :             LeftX2 = aWindowBox.Width - gnHorizontalGap;
     322           0 :             RightX1 = gnHorizontalGap;
     323           0 :             RightX2 = aWindowBox.Width/2 - gnHorizontalGap;
     324             :         }
     325             :         const double nLeftHeight (
     326           0 :             (*iBlock)->maLeft.Paint(mxCanvas,
     327             :                 geometry::RealRectangle2D(
     328             :                         LeftX1,
     329             :                         nY,
     330             :                         LeftX2,
     331           0 :                         aWindowBox.Height - gnVerticalBorder),
     332             :                 false,
     333             :                 aViewState,
     334             :                 aRenderState,
     335           0 :                 mpFont->mxFont));
     336             :         const double nRightHeight (
     337           0 :             (*iBlock)->maRight.Paint(mxCanvas,
     338             :                 geometry::RealRectangle2D(
     339             :                         RightX1,
     340             :                         nY,
     341             :                         RightX2,
     342           0 :                         aWindowBox.Height - gnVerticalBorder),
     343             :                 true,
     344             :                 aViewState,
     345             :                 aRenderState,
     346           0 :                 mpFont->mxFont));
     347             : 
     348           0 :         nY += ::std::max(nLeftHeight,nRightHeight);
     349             :     }
     350             : 
     351           0 :     Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
     352           0 :     if (xSpriteCanvas.is())
     353           0 :         xSpriteCanvas->updateScreen(sal_False);
     354             : }
     355             : 
     356           0 : void PresenterHelpView::ReadHelpStrings (void)
     357             : {
     358           0 :     mpTextContainer.reset(new TextContainer());
     359             :     PresenterConfigurationAccess aConfiguration (
     360             :         mxComponentContext,
     361             :         OUString("/org.openoffice.Office.PresenterScreen/"),
     362           0 :         PresenterConfigurationAccess::READ_ONLY);
     363             :     Reference<container::XNameAccess> xStrings (
     364             :         aConfiguration.GetConfigurationNode("PresenterScreenSettings/HelpView/HelpStrings"),
     365           0 :         UNO_QUERY);
     366             :     PresenterConfigurationAccess::ForAll(
     367             :         xStrings,
     368           0 :         ::boost::bind(&PresenterHelpView::ProcessString, this, _2));
     369           0 : }
     370             : 
     371           0 : void PresenterHelpView::ProcessString (
     372             :     const Reference<beans::XPropertySet>& rsProperties)
     373             : {
     374           0 :     if ( ! rsProperties.is())
     375           0 :         return;
     376             : 
     377           0 :     OUString sLeftText;
     378           0 :     PresenterConfigurationAccess::GetProperty(rsProperties, "Left") >>= sLeftText;
     379           0 :     OUString sRightText;
     380           0 :     PresenterConfigurationAccess::GetProperty(rsProperties, "Right") >>= sRightText;
     381           0 :     mpTextContainer->push_back(
     382             :         ::boost::shared_ptr<Block>(
     383           0 :             new Block(sLeftText, sRightText, mpFont->mxFont, mnMaximalWidth)));
     384             : }
     385             : 
     386           0 : void PresenterHelpView::CheckFontSize (void)
     387             : {
     388           0 :     if (mpFont.get() == NULL)
     389           0 :         return;
     390             : 
     391           0 :     sal_Int32 nBestSize (6);
     392             : 
     393             :     // Scaling down and then reformatting can cause the text to be too large
     394             :     // still.  So do this again and again until the text size is
     395             :     // small enough.  Restrict the number of loops.
     396           0 :     for (int nLoopCount=0; nLoopCount<5; ++nLoopCount)
     397             :     {
     398           0 :         double nY (0.0);
     399           0 :         TextContainer::iterator iBlock (mpTextContainer->begin());
     400           0 :         TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
     401           0 :         for ( ; iBlock!=iBlockEnd; ++iBlock)
     402             :             nY += ::std::max(
     403           0 :                 (*iBlock)->maLeft.GetHeight(),
     404           0 :                 (*iBlock)->maRight.GetHeight());
     405             : 
     406           0 :         const double nHeightDifference (nY - (mnSeparatorY-gnVerticalBorder));
     407           0 :         if (nHeightDifference <= 0 && nHeightDifference > -50)
     408             :         {
     409             :             // We have found a good font size that is large and leaves not
     410             :             // too much space below the help text.
     411           0 :             return;
     412             :         }
     413             : 
     414             :         // Use a simple linear transformation to calculate initial guess of
     415             :         // a size that lets all help text be shown inside the window.
     416           0 :         const double nScale (double(mnSeparatorY-gnVerticalBorder) / nY);
     417           0 :         if (nScale > 1.0 && nScale < 1.05)
     418           0 :             break;
     419             : 
     420           0 :         sal_Int32 nFontSizeGuess (sal_Int32(mpFont->mnSize * nScale));
     421           0 :         if (nHeightDifference<=0 && mpFont->mnSize>nBestSize)
     422           0 :             nBestSize = mpFont->mnSize;
     423           0 :         mpFont->mnSize = nFontSizeGuess;
     424           0 :         mpFont->mxFont = NULL;
     425           0 :         mpFont->PrepareFont(mxCanvas);
     426             : 
     427             :         // Reformat blocks.
     428           0 :         for (iBlock=mpTextContainer->begin(); iBlock!=iBlockEnd; ++iBlock)
     429           0 :             (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
     430             :     }
     431             : 
     432           0 :     if (nBestSize != mpFont->mnSize)
     433             :     {
     434           0 :         mpFont->mnSize = nBestSize;
     435           0 :         mpFont->mxFont = NULL;
     436           0 :         mpFont->PrepareFont(mxCanvas);
     437             : 
     438             :         // Reformat blocks.
     439           0 :         for (TextContainer::iterator
     440           0 :                  iBlock (mpTextContainer->begin()),
     441           0 :                  iEnd (mpTextContainer->end());
     442             :              iBlock!=iEnd;
     443             :              ++iBlock)
     444             :         {
     445           0 :             (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
     446             :         }
     447             :     }
     448             : }
     449             : 
     450             : //----- XResourceId -----------------------------------------------------------
     451             : 
     452           0 : Reference<XResourceId> SAL_CALL PresenterHelpView::getResourceId (void)
     453             :     throw (RuntimeException, std::exception)
     454             : {
     455           0 :     ThrowIfDisposed();
     456           0 :     return mxViewId;
     457             : }
     458             : 
     459           0 : sal_Bool SAL_CALL PresenterHelpView::isAnchorOnly (void)
     460             :     throw (RuntimeException, std::exception)
     461             : {
     462           0 :     return false;
     463             : }
     464             : 
     465             : 
     466             : 
     467           0 : void PresenterHelpView::ProvideCanvas (void)
     468             : {
     469           0 :     if ( ! mxCanvas.is() && mxPane.is())
     470             :     {
     471           0 :         mxCanvas = mxPane->getCanvas();
     472           0 :         if ( ! mxCanvas.is())
     473           0 :             return;
     474           0 :         Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
     475           0 :         if (xComponent.is())
     476           0 :             xComponent->addEventListener(static_cast<awt::XPaintListener*>(this));
     477             : 
     478           0 :         if (mpCloseButton.is())
     479           0 :             mpCloseButton->SetCanvas(mxCanvas, mxWindow);
     480             :     }
     481             : }
     482             : 
     483           0 : void PresenterHelpView::Resize (void)
     484             : {
     485           0 :     if (mpCloseButton.get() != NULL && mxWindow.is())
     486             :     {
     487           0 :         const awt::Rectangle aWindowBox (mxWindow->getPosSize());
     488           0 :         mnMaximalWidth = (mxWindow->getPosSize().Width - 4*gnHorizontalGap) / 2;
     489             : 
     490             :         // Place vertical separator.
     491             :         mnSeparatorY = aWindowBox.Height
     492           0 :             - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
     493             : 
     494             :         mpCloseButton->SetCenter(geometry::RealPoint2D(
     495           0 :             aWindowBox.Width/2,
     496           0 :             aWindowBox.Height - mpCloseButton->GetSize().Height/2));
     497             : 
     498           0 :         CheckFontSize();
     499             :     }
     500           0 : }
     501             : 
     502           0 : void PresenterHelpView::ThrowIfDisposed (void)
     503             :     throw (lang::DisposedException)
     504             : {
     505           0 :     if (rBHelper.bDisposed || rBHelper.bInDispose)
     506             :     {
     507             :         throw lang::DisposedException (
     508             :             OUString( "PresenterHelpView has been already disposed"),
     509           0 :             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
     510             :     }
     511           0 : }
     512             : 
     513             : //===== LineDescritor =========================================================
     514             : 
     515             : namespace {
     516             : 
     517           0 : LineDescriptor::LineDescriptor (void)
     518             :     : msLine(),
     519             :       maSize(0,0),
     520           0 :       mnVerticalOffset(0)
     521             : {
     522           0 : }
     523             : 
     524           0 : void LineDescriptor::AddPart (
     525             :     const OUString& rsLine,
     526             :     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
     527             : {
     528           0 :     msLine += rsLine;
     529             : 
     530           0 :     CalculateSize(rxFont);
     531           0 : }
     532             : 
     533           0 : bool LineDescriptor::IsEmpty (void) const
     534             : {
     535           0 :     return msLine.isEmpty();
     536             : }
     537             : 
     538           0 : void LineDescriptor::CalculateSize (
     539             :     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
     540             : {
     541             :     OSL_ASSERT(rxFont.is());
     542             : 
     543           0 :     rendering::StringContext aContext (msLine, 0, msLine.getLength());
     544             :     Reference<rendering::XTextLayout> xLayout (
     545           0 :         rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
     546           0 :     const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
     547           0 :     maSize = css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1);
     548           0 :     mnVerticalOffset = aTextBBox.Y2;
     549           0 : }
     550             : 
     551             : } // end of anonymous namespace
     552             : 
     553             : //===== LineDescriptorList ====================================================
     554             : 
     555             : namespace {
     556             : 
     557           0 : LineDescriptorList::LineDescriptorList (
     558             :     const OUString& rsText,
     559             :     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
     560             :     const sal_Int32 nMaximalWidth)
     561           0 :     : msText(rsText)
     562             : {
     563           0 :     Update(rxFont, nMaximalWidth);
     564           0 : }
     565             : 
     566           0 : double LineDescriptorList::Paint(
     567             :     const Reference<rendering::XCanvas>& rxCanvas,
     568             :     const geometry::RealRectangle2D& rBBox,
     569             :     const bool bFlushLeft,
     570             :     const rendering::ViewState& rViewState,
     571             :     rendering::RenderState& rRenderState,
     572             :     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const
     573             : {
     574           0 :     if ( ! rxCanvas.is())
     575           0 :         return 0;
     576             : 
     577           0 :     double nY (rBBox.Y1);
     578           0 :     vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
     579           0 :     vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
     580           0 :     for ( ; iLine!=iEnd; ++iLine)
     581             :     {
     582             :         double nX;
     583             :         /// check whether RTL interface or not
     584           0 :         if(!Application::GetSettings().GetLayoutRTL())
     585             :         {
     586           0 :             nX = rBBox.X1;
     587           0 :             if ( ! bFlushLeft)
     588           0 :                 nX = rBBox.X2 - iLine->maSize.Width;
     589             :         }
     590             :         else
     591             :         {
     592           0 :             nX=rBBox.X2 - iLine->maSize.Width;
     593           0 :             if ( ! bFlushLeft)
     594           0 :                 nX = rBBox.X1;
     595             :         }
     596           0 :         rRenderState.AffineTransform.m02 = nX;
     597           0 :         rRenderState.AffineTransform.m12 = nY + iLine->maSize.Height - iLine->mnVerticalOffset;
     598             : 
     599           0 :         const rendering::StringContext aContext (iLine->msLine, 0, iLine->msLine.getLength());
     600             :         Reference<rendering::XTextLayout> xLayout (
     601           0 :         rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
     602           0 :         rxCanvas->drawTextLayout (
     603             :             xLayout,
     604             :             rViewState,
     605           0 :             rRenderState);
     606             : 
     607           0 :         nY += iLine->maSize.Height * 1.2;
     608           0 :     }
     609             : 
     610           0 :     return nY - rBBox.Y1;
     611             : }
     612             : 
     613           0 : double LineDescriptorList::GetHeight (void) const
     614             : {
     615           0 :     double nHeight (0);
     616           0 :     vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
     617           0 :     vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
     618           0 :     for ( ; iLine!=iEnd; ++iLine)
     619           0 :         nHeight += iLine->maSize.Height * 1.2;
     620             : 
     621           0 :     return nHeight;
     622             : }
     623             : 
     624           0 : void LineDescriptorList::Update (
     625             :     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
     626             :     const sal_Int32 nMaximalWidth)
     627             : {
     628           0 :     vector<OUString> aTextParts;
     629           0 :     SplitText(msText, aTextParts);
     630           0 :     FormatText(aTextParts, rxFont, nMaximalWidth);
     631           0 : }
     632             : 
     633           0 : void LineDescriptorList::SplitText (
     634             :     const OUString& rsText,
     635             :     vector<OUString>& rTextParts)
     636             : {
     637           0 :     const sal_Char cQuote ('\'');
     638           0 :     const sal_Char cSeparator (',');
     639             : 
     640           0 :     sal_Int32 nIndex (0);
     641           0 :     sal_Int32 nStart (0);
     642           0 :     sal_Int32 nLength (rsText.getLength());
     643           0 :     bool bIsQuoted (false);
     644           0 :     while (nIndex < nLength)
     645             :     {
     646           0 :         const sal_Int32 nQuoteIndex (rsText.indexOf(cQuote, nIndex));
     647           0 :         const sal_Int32 nSeparatorIndex (rsText.indexOf(cSeparator, nIndex));
     648           0 :         if (nQuoteIndex>=0 && (nSeparatorIndex==-1 || nQuoteIndex<nSeparatorIndex))
     649             :         {
     650           0 :             bIsQuoted = !bIsQuoted;
     651           0 :             nIndex = nQuoteIndex+1;
     652           0 :             continue;
     653             :         }
     654             : 
     655           0 :         const sal_Int32 nNextIndex = nSeparatorIndex;
     656           0 :         if (nNextIndex < 0)
     657             :         {
     658           0 :             break;
     659             :         }
     660           0 :         else if ( ! bIsQuoted)
     661             :         {
     662           0 :             rTextParts.push_back(rsText.copy(nStart, nNextIndex-nStart));
     663           0 :             nStart = nNextIndex + 1;
     664             :         }
     665           0 :         nIndex = nNextIndex+1;
     666             :     }
     667           0 :     if (nStart < nLength)
     668           0 :         rTextParts.push_back(rsText.copy(nStart, nLength-nStart));
     669           0 : }
     670             : 
     671           0 : void LineDescriptorList::FormatText (
     672             :     const vector<OUString>& rTextParts,
     673             :     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
     674             :     const sal_Int32 nMaximalWidth)
     675             : {
     676           0 :     LineDescriptor aLineDescriptor;
     677             : 
     678           0 :     mpLineDescriptors.reset(new vector<LineDescriptor>());
     679             : 
     680           0 :     vector<OUString>::const_iterator iPart (rTextParts.begin());
     681           0 :     vector<OUString>::const_iterator iEnd (rTextParts.end());
     682           0 :     while (iPart!=iEnd)
     683             :     {
     684           0 :         if (aLineDescriptor.IsEmpty())
     685             :         {
     686             :             // Avoid empty lines.
     687           0 :             if (PresenterCanvasHelper::GetTextSize(
     688           0 :                 rxFont, *iPart).Width > nMaximalWidth)
     689             :             {
     690           0 :                 const sal_Char cSpace (' ');
     691             : 
     692           0 :                 sal_Int32 nIndex (0);
     693           0 :                 sal_Int32 nStart (0);
     694           0 :                 sal_Int32 nLength (iPart->getLength());
     695           0 :                 while (nIndex < nLength)
     696             :                 {
     697           0 :                     sal_Int32  nSpaceIndex (iPart->indexOf(cSpace, nIndex));
     698           0 :                     while (nSpaceIndex >= 0 && PresenterCanvasHelper::GetTextSize(
     699           0 :                         rxFont, iPart->copy(nStart, nSpaceIndex-nStart)).Width <= nMaximalWidth)
     700             :                     {
     701           0 :                         nIndex = nSpaceIndex;
     702           0 :                         nSpaceIndex = iPart->indexOf(cSpace, nIndex+1);
     703             :                     }
     704             : 
     705           0 :                     if (nSpaceIndex < 0 && PresenterCanvasHelper::GetTextSize(
     706           0 :                         rxFont, iPart->copy(nStart, nLength-nStart)).Width <= nMaximalWidth)
     707             :                     {
     708           0 :                         nIndex = nLength;
     709             :                     }
     710             : 
     711           0 :                     if (nIndex == nStart)
     712             :                     {
     713           0 :                         nIndex = nLength;
     714             :                     }
     715             : 
     716           0 :                     aLineDescriptor.AddPart(iPart->copy(nStart, nIndex-nStart), rxFont);
     717           0 :                     if (nIndex != nLength)
     718             :                     {
     719           0 :                         mpLineDescriptors->push_back(aLineDescriptor);
     720           0 :                         aLineDescriptor = LineDescriptor();
     721             :                     }
     722           0 :                     nStart = nIndex;
     723             :                 }
     724             :             }
     725             :             else
     726             :             {
     727           0 :                 aLineDescriptor.AddPart(*iPart, rxFont);
     728             :             }
     729             :         }
     730           0 :         else if (PresenterCanvasHelper::GetTextSize(
     731           0 :             rxFont, aLineDescriptor.msLine+", "+*iPart).Width > nMaximalWidth)
     732             :         {
     733           0 :             aLineDescriptor.AddPart(",", rxFont);
     734           0 :             mpLineDescriptors->push_back(aLineDescriptor);
     735           0 :             aLineDescriptor = LineDescriptor();
     736           0 :             continue;
     737             :         }
     738             :         else
     739             :         {
     740           0 :             aLineDescriptor.AddPart(", "+*iPart, rxFont);
     741             :         }
     742           0 :         ++iPart;
     743             :     }
     744           0 :     if ( ! aLineDescriptor.IsEmpty())
     745             :     {
     746           0 :         mpLineDescriptors->push_back(aLineDescriptor);
     747           0 :     }
     748           0 : }
     749             : 
     750             : } // end of anonymous namespace
     751             : 
     752             : //===== Block =================================================================
     753             : 
     754             : namespace {
     755             : 
     756           0 : Block::Block (
     757             :     const OUString& rsLeftText,
     758             :     const OUString& rsRightText,
     759             :     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
     760             :     const sal_Int32 nMaximalWidth)
     761             :     : maLeft(rsLeftText, rxFont, nMaximalWidth),
     762           0 :       maRight(rsRightText, rxFont, nMaximalWidth)
     763             : {
     764           0 : }
     765             : 
     766           0 : void Block::Update (
     767             :     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
     768             :     const sal_Int32 nMaximalWidth)
     769             : {
     770           0 :     maLeft.Update(rxFont, nMaximalWidth);
     771           0 :     maRight.Update(rxFont, nMaximalWidth);
     772           0 : }
     773             : 
     774             : } // end of anonymous namespace
     775             : 
     776          12 : } } // end of namespace ::sdext::presenter
     777             : 
     778             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10