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

Generated by: LCOV version 1.10