Updated core
[LibreOffice.git] / sdext / source / presenter / PresenterHelpView.cxx
blob70fe8b87af17a2c4965980490e1094e71f251936
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::drawing::framework;
40 using ::std::vector;
42 namespace sdext { namespace presenter {
44 namespace {
45 const static sal_Int32 gnHorizontalGap (20);
46 const static sal_Int32 gnVerticalBorder (30);
47 const static sal_Int32 gnVerticalButtonPadding (12);
49 class LineDescriptor
51 public:
52 LineDescriptor(void);
53 void AddPart (
54 const OUString& rsLine,
55 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
56 bool IsEmpty (void) const;
58 OUString msLine;
59 geometry::RealSize2D maSize;
60 double mnVerticalOffset;
62 void CalculateSize (const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
65 class LineDescriptorList
67 public:
68 LineDescriptorList (
69 const OUString& rsText,
70 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
71 const sal_Int32 nMaximalWidth);
73 void Update (
74 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
75 const sal_Int32 nMaximalWidth);
77 double Paint(
78 const Reference<rendering::XCanvas>& rxCanvas,
79 const geometry::RealRectangle2D& rBBox,
80 const bool bFlushLeft,
81 const rendering::ViewState& rViewState,
82 rendering::RenderState& rRenderState,
83 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const;
84 double GetHeight (void) const;
86 private:
87 const OUString msText;
88 ::boost::shared_ptr<vector<LineDescriptor> > mpLineDescriptors;
90 void SplitText (const OUString& rsText, vector<OUString>& rTextParts);
91 void FormatText (
92 const vector<OUString>& rTextParts,
93 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
94 const sal_Int32 nMaximalWidth);
97 class Block
99 public:
100 Block (const Block& rBlock);
101 Block (
102 const OUString& rsLeftText,
103 const OUString& rsRightText,
104 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
105 const sal_Int32 nMaximalWidth);
106 void Update (
107 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
108 const sal_Int32 nMaximalWidth);
110 LineDescriptorList maLeft;
111 LineDescriptorList maRight;
113 } // end of anonymous namespace
115 class PresenterHelpView::TextContainer : public vector<boost::shared_ptr<Block> >
119 PresenterHelpView::PresenterHelpView (
120 const Reference<uno::XComponentContext>& rxContext,
121 const Reference<XResourceId>& rxViewId,
122 const Reference<frame::XController>& rxController,
123 const ::rtl::Reference<PresenterController>& rpPresenterController)
124 : PresenterHelpViewInterfaceBase(m_aMutex),
125 mxComponentContext(rxContext),
126 mxViewId(rxViewId),
127 mxPane(),
128 mxWindow(),
129 mxCanvas(),
130 mpPresenterController(rpPresenterController),
131 mpFont(),
132 mpTextContainer(),
133 mpCloseButton(),
134 mnSeparatorY(0),
135 mnMaximalWidth(0)
139 // Get the content window via the pane anchor.
140 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
141 Reference<XConfigurationController> xCC (
142 xCM->getConfigurationController(), UNO_QUERY_THROW);
143 mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
145 mxWindow = mxPane->getWindow();
146 ProvideCanvas();
148 mxWindow->addWindowListener(this);
149 mxWindow->addPaintListener(this);
150 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
151 if (xPeer.is())
152 xPeer->setBackground(util::Color(0xff000000));
153 mxWindow->setVisible(sal_True);
155 if (mpPresenterController.is())
157 mpFont = mpPresenterController->GetViewFont(mxViewId->getResourceURL());
158 if (mpFont.get() != NULL)
160 mpFont->PrepareFont(mxCanvas);
164 // Create the close button.
165 mpCloseButton = PresenterButton::Create(
166 mxComponentContext,
167 mpPresenterController,
168 mpPresenterController->GetTheme(),
169 mxWindow,
170 mxCanvas,
171 "HelpViewCloser");
173 ReadHelpStrings();
174 Resize();
176 catch (RuntimeException&)
178 mxViewId = NULL;
179 mxWindow = NULL;
180 throw;
184 PresenterHelpView::~PresenterHelpView (void)
188 void SAL_CALL PresenterHelpView::disposing (void)
190 mxViewId = NULL;
192 if (mpCloseButton.is())
194 Reference<lang::XComponent> xComponent (
195 static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
196 mpCloseButton = NULL;
197 if (xComponent.is())
198 xComponent->dispose();
201 if (mxWindow.is())
203 mxWindow->removeWindowListener(this);
204 mxWindow->removePaintListener(this);
208 //----- lang::XEventListener --------------------------------------------------
210 void SAL_CALL PresenterHelpView::disposing (const lang::EventObject& rEventObject)
211 throw (RuntimeException)
213 if (rEventObject.Source == mxCanvas)
215 mxCanvas = NULL;
217 else if (rEventObject.Source == mxWindow)
219 mxWindow = NULL;
220 dispose();
224 //----- XWindowListener -------------------------------------------------------
226 void SAL_CALL PresenterHelpView::windowResized (const awt::WindowEvent& rEvent)
227 throw (uno::RuntimeException)
229 (void)rEvent;
230 ThrowIfDisposed();
231 Resize();
234 void SAL_CALL PresenterHelpView::windowMoved (const awt::WindowEvent& rEvent)
235 throw (uno::RuntimeException)
237 (void)rEvent;
238 ThrowIfDisposed();
241 void SAL_CALL PresenterHelpView::windowShown (const lang::EventObject& rEvent)
242 throw (uno::RuntimeException)
244 (void)rEvent;
245 ThrowIfDisposed();
246 Resize();
249 void SAL_CALL PresenterHelpView::windowHidden (const lang::EventObject& rEvent)
250 throw (uno::RuntimeException)
252 (void)rEvent;
253 ThrowIfDisposed();
256 //----- XPaintListener --------------------------------------------------------
258 void SAL_CALL PresenterHelpView::windowPaint (const css::awt::PaintEvent& rEvent)
259 throw (RuntimeException)
261 Paint(rEvent.UpdateRect);
264 void PresenterHelpView::Paint (const awt::Rectangle& rUpdateBox)
266 ProvideCanvas();
267 if ( ! mxCanvas.is())
268 return;
270 // Clear background.
271 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
272 mpPresenterController->GetCanvasHelper()->Paint(
273 mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
274 Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY),
275 rUpdateBox,
276 awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
277 awt::Rectangle());
279 // Paint vertical divider.
281 rendering::ViewState aViewState(
282 geometry::AffineMatrix2D(1,0,0, 0,1,0),
283 PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice()));
285 rendering::RenderState aRenderState (
286 geometry::AffineMatrix2D(1,0,0, 0,1,0),
287 NULL,
288 Sequence<double>(4),
289 rendering::CompositeOperation::SOURCE);
290 PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
292 mxCanvas->drawLine(
293 geometry::RealPoint2D(aWindowBox.Width/2, gnVerticalBorder),
294 geometry::RealPoint2D(aWindowBox.Width/2, mnSeparatorY - gnVerticalBorder),
295 aViewState,
296 aRenderState);
298 // Paint the horizontal separator.
299 mxCanvas->drawLine(
300 geometry::RealPoint2D(0, mnSeparatorY),
301 geometry::RealPoint2D(aWindowBox.Width, mnSeparatorY),
302 aViewState,
303 aRenderState);
305 // Paint text.
306 double nY (gnVerticalBorder);
307 TextContainer::const_iterator iBlock (mpTextContainer->begin());
308 TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
309 for ( ; iBlock!=iBlockEnd; ++iBlock)
311 sal_Int32 LeftX1 = gnHorizontalGap;
312 sal_Int32 LeftX2 = aWindowBox.Width/2 - gnHorizontalGap;
313 sal_Int32 RightX1 = aWindowBox.Width/2 + gnHorizontalGap;
314 sal_Int32 RightX2 = aWindowBox.Width - gnHorizontalGap;
315 /* check whether RTL interface or not
316 then replace the windowbox position */
317 if(Application::GetSettings().GetLayoutRTL())
319 LeftX1 = aWindowBox.Width/2 + gnHorizontalGap;
320 LeftX2 = aWindowBox.Width - gnHorizontalGap;
321 RightX1 = gnHorizontalGap;
322 RightX2 = aWindowBox.Width/2 - gnHorizontalGap;
324 const double nLeftHeight (
325 (*iBlock)->maLeft.Paint(mxCanvas,
326 geometry::RealRectangle2D(
327 LeftX1,
329 LeftX2,
330 aWindowBox.Height - gnVerticalBorder),
331 false,
332 aViewState,
333 aRenderState,
334 mpFont->mxFont));
335 const double nRightHeight (
336 (*iBlock)->maRight.Paint(mxCanvas,
337 geometry::RealRectangle2D(
338 RightX1,
340 RightX2,
341 aWindowBox.Height - gnVerticalBorder),
342 true,
343 aViewState,
344 aRenderState,
345 mpFont->mxFont));
347 nY += ::std::max(nLeftHeight,nRightHeight);
350 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
351 if (xSpriteCanvas.is())
352 xSpriteCanvas->updateScreen(sal_False);
355 void PresenterHelpView::ReadHelpStrings (void)
357 mpTextContainer.reset(new TextContainer());
358 PresenterConfigurationAccess aConfiguration (
359 mxComponentContext,
360 OUString("/org.openoffice.Office.PresenterScreen/"),
361 PresenterConfigurationAccess::READ_ONLY);
362 Reference<container::XNameAccess> xStrings (
363 aConfiguration.GetConfigurationNode("PresenterScreenSettings/HelpView/HelpStrings"),
364 UNO_QUERY);
365 PresenterConfigurationAccess::ForAll(
366 xStrings,
367 ::boost::bind(&PresenterHelpView::ProcessString, this, _2));
370 void PresenterHelpView::ProcessString (
371 const Reference<beans::XPropertySet>& rsProperties)
373 if ( ! rsProperties.is())
374 return;
376 OUString sLeftText;
377 PresenterConfigurationAccess::GetProperty(rsProperties, "Left") >>= sLeftText;
378 OUString sRightText;
379 PresenterConfigurationAccess::GetProperty(rsProperties, "Right") >>= sRightText;
380 mpTextContainer->push_back(
381 ::boost::shared_ptr<Block>(
382 new Block(sLeftText, sRightText, mpFont->mxFont, mnMaximalWidth)));
385 void PresenterHelpView::CheckFontSize (void)
387 if (mpFont.get() == NULL)
388 return;
390 sal_Int32 nBestSize (6);
392 // Scaling down and then reformatting can cause the text to be too large
393 // still. So do this again and again until the text size is
394 // small enough. Restrict the number of loops.
395 for (int nLoopCount=0; nLoopCount<5; ++nLoopCount)
397 double nY (0.0);
398 TextContainer::iterator iBlock (mpTextContainer->begin());
399 TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
400 for ( ; iBlock!=iBlockEnd; ++iBlock)
401 nY += ::std::max(
402 (*iBlock)->maLeft.GetHeight(),
403 (*iBlock)->maRight.GetHeight());
405 const double nHeightDifference (nY - (mnSeparatorY-gnVerticalBorder));
406 if (nHeightDifference <= 0 && nHeightDifference > -50)
408 // We have found a good font size that is large and leaves not
409 // too much space below the help text.
410 return;
413 // Use a simple linear transformation to calculate initial guess of
414 // a size that lets all help text be shown inside the window.
415 const double nScale (double(mnSeparatorY-gnVerticalBorder) / nY);
416 if (nScale > 1.0 && nScale < 1.05)
417 break;
419 sal_Int32 nFontSizeGuess (sal_Int32(mpFont->mnSize * nScale));
420 if (nHeightDifference<=0 && mpFont->mnSize>nBestSize)
421 nBestSize = mpFont->mnSize;
422 mpFont->mnSize = nFontSizeGuess;
423 mpFont->mxFont = NULL;
424 mpFont->PrepareFont(mxCanvas);
426 // Reformat blocks.
427 for (iBlock=mpTextContainer->begin(); iBlock!=iBlockEnd; ++iBlock)
428 (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
431 if (nBestSize != mpFont->mnSize)
433 mpFont->mnSize = nBestSize;
434 mpFont->mxFont = NULL;
435 mpFont->PrepareFont(mxCanvas);
437 // Reformat blocks.
438 for (TextContainer::iterator
439 iBlock (mpTextContainer->begin()),
440 iEnd (mpTextContainer->end());
441 iBlock!=iEnd;
442 ++iBlock)
444 (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
449 //----- XResourceId -----------------------------------------------------------
451 Reference<XResourceId> SAL_CALL PresenterHelpView::getResourceId (void)
452 throw (RuntimeException)
454 ThrowIfDisposed();
455 return mxViewId;
458 sal_Bool SAL_CALL PresenterHelpView::isAnchorOnly (void)
459 throw (RuntimeException)
461 return false;
464 //-----------------------------------------------------------------------------
466 void PresenterHelpView::ProvideCanvas (void)
468 if ( ! mxCanvas.is() && mxPane.is())
470 mxCanvas = mxPane->getCanvas();
471 if ( ! mxCanvas.is())
472 return;
473 Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
474 if (xComponent.is())
475 xComponent->addEventListener(static_cast<awt::XPaintListener*>(this));
477 if (mpCloseButton.is())
478 mpCloseButton->SetCanvas(mxCanvas, mxWindow);
482 void PresenterHelpView::Resize (void)
484 if (mpCloseButton.get() != NULL && mxWindow.is())
486 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
487 mnMaximalWidth = (mxWindow->getPosSize().Width - 4*gnHorizontalGap) / 2;
489 // Place vertical separator.
490 mnSeparatorY = aWindowBox.Height
491 - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
493 mpCloseButton->SetCenter(geometry::RealPoint2D(
494 aWindowBox.Width/2,
495 aWindowBox.Height - mpCloseButton->GetSize().Height/2));
497 CheckFontSize();
501 void PresenterHelpView::ThrowIfDisposed (void)
502 throw (lang::DisposedException)
504 if (rBHelper.bDisposed || rBHelper.bInDispose)
506 throw lang::DisposedException (
507 OUString( "PresenterHelpView has been already disposed"),
508 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
512 //===== LineDescritor =========================================================
514 namespace {
516 LineDescriptor::LineDescriptor (void)
517 : msLine(),
518 maSize(0,0),
519 mnVerticalOffset(0)
523 void LineDescriptor::AddPart (
524 const OUString& rsLine,
525 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
527 msLine += rsLine;
529 CalculateSize(rxFont);
532 bool LineDescriptor::IsEmpty (void) const
534 return msLine.isEmpty();
537 void LineDescriptor::CalculateSize (
538 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
540 OSL_ASSERT(rxFont.is());
542 rendering::StringContext aContext (msLine, 0, msLine.getLength());
543 Reference<rendering::XTextLayout> xLayout (
544 rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
545 const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
546 maSize = css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1);
547 mnVerticalOffset = aTextBBox.Y2;
550 } // end of anonymous namespace
552 //===== LineDescriptorList ====================================================
554 namespace {
556 LineDescriptorList::LineDescriptorList (
557 const OUString& rsText,
558 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
559 const sal_Int32 nMaximalWidth)
560 : msText(rsText)
562 Update(rxFont, nMaximalWidth);
565 double LineDescriptorList::Paint(
566 const Reference<rendering::XCanvas>& rxCanvas,
567 const geometry::RealRectangle2D& rBBox,
568 const bool bFlushLeft,
569 const rendering::ViewState& rViewState,
570 rendering::RenderState& rRenderState,
571 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const
573 if ( ! rxCanvas.is())
574 return 0;
576 double nY (rBBox.Y1);
577 vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
578 vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
579 for ( ; iLine!=iEnd; ++iLine)
581 double nX;
582 /// check whether RTL interface or not
583 if(!Application::GetSettings().GetLayoutRTL())
585 nX = rBBox.X1;
586 if ( ! bFlushLeft)
587 nX = rBBox.X2 - iLine->maSize.Width;
589 else
591 nX=rBBox.X2 - iLine->maSize.Width;
592 if ( ! bFlushLeft)
593 nX = rBBox.X1;
595 rRenderState.AffineTransform.m02 = nX;
596 rRenderState.AffineTransform.m12 = nY + iLine->maSize.Height - iLine->mnVerticalOffset;
598 const rendering::StringContext aContext (iLine->msLine, 0, iLine->msLine.getLength());
599 Reference<rendering::XTextLayout> xLayout (
600 rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
601 rxCanvas->drawTextLayout (
602 xLayout,
603 rViewState,
604 rRenderState);
606 nY += iLine->maSize.Height * 1.2;
609 return nY - rBBox.Y1;
612 double LineDescriptorList::GetHeight (void) const
614 double nHeight (0);
615 vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
616 vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
617 for ( ; iLine!=iEnd; ++iLine)
618 nHeight += iLine->maSize.Height * 1.2;
620 return nHeight;
623 void LineDescriptorList::Update (
624 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
625 const sal_Int32 nMaximalWidth)
627 vector<OUString> aTextParts;
628 SplitText(msText, aTextParts);
629 FormatText(aTextParts, rxFont, nMaximalWidth);
632 void LineDescriptorList::SplitText (
633 const OUString& rsText,
634 vector<OUString>& rTextParts)
636 const sal_Char cQuote ('\'');
637 const sal_Char cSeparator (',');
639 sal_Int32 nIndex (0);
640 sal_Int32 nStart (0);
641 sal_Int32 nLength (rsText.getLength());
642 bool bIsQuoted (false);
643 while (nIndex < nLength)
645 const sal_Int32 nQuoteIndex (rsText.indexOf(cQuote, nIndex));
646 const sal_Int32 nSeparatorIndex (rsText.indexOf(cSeparator, nIndex));
647 if (nQuoteIndex>=0 && (nSeparatorIndex==-1 || nQuoteIndex<nSeparatorIndex))
649 bIsQuoted = !bIsQuoted;
650 nIndex = nQuoteIndex+1;
651 continue;
654 const sal_Int32 nNextIndex = nSeparatorIndex;
655 if (nNextIndex < 0)
657 break;
659 else if ( ! bIsQuoted)
661 rTextParts.push_back(rsText.copy(nStart, nNextIndex-nStart));
662 nStart = nNextIndex + 1;
664 nIndex = nNextIndex+1;
666 if (nStart < nLength)
667 rTextParts.push_back(rsText.copy(nStart, nLength-nStart));
670 void LineDescriptorList::FormatText (
671 const vector<OUString>& rTextParts,
672 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
673 const sal_Int32 nMaximalWidth)
675 LineDescriptor aLineDescriptor;
677 mpLineDescriptors.reset(new vector<LineDescriptor>());
679 vector<OUString>::const_iterator iPart (rTextParts.begin());
680 vector<OUString>::const_iterator iEnd (rTextParts.end());
681 while (iPart!=iEnd)
683 if (aLineDescriptor.IsEmpty())
685 // Avoid empty lines.
686 if (PresenterCanvasHelper::GetTextSize(
687 rxFont, *iPart).Width > nMaximalWidth)
689 const sal_Char cSpace (' ');
691 sal_Int32 nIndex (0);
692 sal_Int32 nStart (0);
693 sal_Int32 nLength (iPart->getLength());
694 while (nIndex < nLength)
696 sal_Int32 nSpaceIndex (iPart->indexOf(cSpace, nIndex));
697 while (nSpaceIndex >= 0 && PresenterCanvasHelper::GetTextSize(
698 rxFont, iPart->copy(nStart, nSpaceIndex-nStart)).Width <= nMaximalWidth)
700 nIndex = nSpaceIndex;
701 nSpaceIndex = iPart->indexOf(cSpace, nIndex+1);
704 if (nSpaceIndex < 0 && PresenterCanvasHelper::GetTextSize(
705 rxFont, iPart->copy(nStart, nLength-nStart)).Width <= nMaximalWidth)
707 nIndex = nLength;
710 if (nIndex == nStart)
712 nIndex = nLength;
715 aLineDescriptor.AddPart(iPart->copy(nStart, nIndex-nStart), rxFont);
716 if (nIndex != nLength)
718 mpLineDescriptors->push_back(aLineDescriptor);
719 aLineDescriptor = LineDescriptor();
721 nStart = nIndex;
724 else
726 aLineDescriptor.AddPart(*iPart, rxFont);
729 else if (PresenterCanvasHelper::GetTextSize(
730 rxFont, aLineDescriptor.msLine+", "+*iPart).Width > nMaximalWidth)
732 aLineDescriptor.AddPart(",", rxFont);
733 mpLineDescriptors->push_back(aLineDescriptor);
734 aLineDescriptor = LineDescriptor();
735 continue;
737 else
739 aLineDescriptor.AddPart(", "+*iPart, rxFont);
741 ++iPart;
743 if ( ! aLineDescriptor.IsEmpty())
745 mpLineDescriptors->push_back(aLineDescriptor);
749 } // end of anonymous namespace
751 //===== Block =================================================================
753 namespace {
755 Block::Block (
756 const OUString& rsLeftText,
757 const OUString& rsRightText,
758 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
759 const sal_Int32 nMaximalWidth)
760 : maLeft(rsLeftText, rxFont, nMaximalWidth),
761 maRight(rsRightText, rxFont, nMaximalWidth)
765 void Block::Update (
766 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
767 const sal_Int32 nMaximalWidth)
769 maLeft.Update(rxFont, nMaximalWidth);
770 maRight.Update(rxFont, nMaximalWidth);
773 } // end of anonymous namespace
775 } } // end of namespace ::sdext::presenter
777 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */