bump product version to 5.0.4.1
[LibreOffice.git] / sdext / source / presenter / PresenterPaneBorderPainter.cxx
blobb40434d32b59d52aef07f4df66a0e21e70b604ed
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 .
20 #include "vcl/svapp.hxx"
21 #include "PresenterPaneBorderPainter.hxx"
22 #include "PresenterCanvasHelper.hxx"
23 #include "PresenterConfigurationAccess.hxx"
24 #include "PresenterGeometryHelper.hxx"
25 #include "PresenterTheme.hxx"
26 #include <com/sun/star/awt/FontDescriptor.hpp>
27 #include <com/sun/star/awt/Point.hpp>
28 #include <com/sun/star/awt/Rectangle.hpp>
29 #include <com/sun/star/awt/SimpleFontMetric.hpp>
30 #include <com/sun/star/awt/XFont.hpp>
31 #include <com/sun/star/drawing/XPresenterHelper.hpp>
32 #include <com/sun/star/graphic/XGraphic.hpp>
33 #include <com/sun/star/graphic/XGraphicRenderer.hpp>
34 #include <com/sun/star/rendering/CompositeOperation.hpp>
35 #include <com/sun/star/rendering/FillRule.hpp>
36 #include <com/sun/star/rendering/TextDirection.hpp>
37 #include <com/sun/star/rendering/XIntegerBitmap.hpp>
38 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
39 #include <map>
40 #include <vector>
41 #include <boost/shared_ptr.hpp>
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::uno;
46 namespace sdext { namespace presenter {
48 namespace {
49 class BorderSize
51 public:
52 BorderSize();
53 sal_Int32 mnLeft;
54 sal_Int32 mnTop;
55 sal_Int32 mnRight;
56 sal_Int32 mnBottom;
59 class RendererPaneStyle
61 public:
62 RendererPaneStyle (
63 const ::boost::shared_ptr<PresenterTheme>& rpTheme,
64 const OUString& rsStyleName);
66 awt::Rectangle AddBorder (
67 const awt::Rectangle& rBox,
68 drawing::framework::BorderType eBorderType) const;
69 awt::Rectangle RemoveBorder (
70 const awt::Rectangle& rBox,
71 drawing::framework::BorderType eBorderType) const;
72 const Reference<rendering::XCanvasFont> GetFont (
73 const Reference<rendering::XCanvas>& rxCanvas) const;
75 SharedBitmapDescriptor mpTopLeft;
76 SharedBitmapDescriptor mpTop;
77 SharedBitmapDescriptor mpTopRight;
78 SharedBitmapDescriptor mpLeft;
79 SharedBitmapDescriptor mpRight;
80 SharedBitmapDescriptor mpBottomLeft;
81 SharedBitmapDescriptor mpBottom;
82 SharedBitmapDescriptor mpBottomRight;
83 SharedBitmapDescriptor mpBottomCallout;
84 SharedBitmapDescriptor mpBackground;
85 SharedBitmapDescriptor mpEmpty;
86 PresenterTheme::SharedFontDescriptor mpFont;
87 sal_Int32 mnFontXOffset;
88 sal_Int32 mnFontYOffset;
89 enum Anchor { AnchorLeft, AnchorRight, AnchorCenter } meFontAnchor;
90 BorderSize maInnerBorderSize;
91 BorderSize maOuterBorderSize;
92 BorderSize maTotalBorderSize;
93 enum Side { Left, Top, Right, Bottom };
94 private:
95 void UpdateBorderSizes();
96 SharedBitmapDescriptor GetBitmap(
97 const ::boost::shared_ptr<PresenterTheme>& rpTheme,
98 const OUString& rsStyleName,
99 const OUString& rsBitmapName);
103 class PresenterPaneBorderPainter::Renderer
105 public:
106 Renderer (
107 const Reference<XComponentContext>& rxContext,
108 const ::boost::shared_ptr<PresenterTheme>& rpTheme);
109 ~Renderer();
111 void SetCanvas (const Reference<rendering::XCanvas>& rxCanvas);
112 void PaintBorder (
113 const OUString& rsTitle,
114 const awt::Rectangle& rBBox,
115 const awt::Rectangle& rUpdateBox,
116 const OUString& rsPaneURL);
117 void PaintTitle (
118 const OUString& rsTitle,
119 const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
120 const awt::Rectangle& rUpdateBox,
121 const awt::Rectangle& rOuterBox,
122 const awt::Rectangle& rInnerBox,
123 const bool bPaintBackground);
124 void SetupClipping (
125 const awt::Rectangle& rUpdateBox,
126 const awt::Rectangle& rOuterBox,
127 const OUString& rsPaneStyleName);
128 ::boost::shared_ptr<RendererPaneStyle> GetRendererPaneStyle (const OUString& rsResourceURL);
129 void SetCalloutAnchor (
130 const awt::Point& rCalloutAnchor);
132 private:
133 ::boost::shared_ptr<PresenterTheme> mpTheme;
134 typedef ::std::map<OUString, ::boost::shared_ptr<RendererPaneStyle> > RendererPaneStyleContainer;
135 RendererPaneStyleContainer maRendererPaneStyles;
136 Reference<rendering::XCanvas> mxCanvas;
137 Reference<drawing::XPresenterHelper> mxPresenterHelper;
138 css::rendering::ViewState maViewState;
139 Reference<rendering::XPolyPolygon2D> mxViewStateClip;
140 bool mbHasCallout;
141 awt::Point maCalloutAnchor;
143 void PaintBitmap(
144 const awt::Rectangle& rBox,
145 const awt::Rectangle& rUpdateBox,
146 const sal_Int32 nXPosition,
147 const sal_Int32 nYPosition,
148 const sal_Int32 nStartOffset,
149 const sal_Int32 nEndOffset,
150 const bool bExpand,
151 const SharedBitmapDescriptor& rpBitmap,
152 const SharedBitmapDescriptor& rpBackgroundBitmap);
155 // ===== PresenterPaneBorderPainter ===========================================
157 PresenterPaneBorderPainter::PresenterPaneBorderPainter (
158 const Reference<XComponentContext>& rxContext)
159 : PresenterPaneBorderPainterInterfaceBase(m_aMutex),
160 mxContext(rxContext),
161 mpTheme(),
162 mpRenderer()
166 PresenterPaneBorderPainter::~PresenterPaneBorderPainter()
170 //----- XPaneBorderPainter ----------------------------------------------------
172 awt::Rectangle SAL_CALL PresenterPaneBorderPainter::addBorder (
173 const OUString& rsPaneBorderStyleName,
174 const css::awt::Rectangle& rRectangle,
175 drawing::framework::BorderType eBorderType)
176 throw(css::uno::RuntimeException, std::exception)
178 ThrowIfDisposed();
180 ProvideTheme();
182 return AddBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
185 awt::Rectangle SAL_CALL PresenterPaneBorderPainter::removeBorder (
186 const OUString& rsPaneBorderStyleName,
187 const css::awt::Rectangle& rRectangle,
188 drawing::framework::BorderType eBorderType)
189 throw(css::uno::RuntimeException, std::exception)
191 ThrowIfDisposed();
193 ProvideTheme();
195 return RemoveBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
198 void SAL_CALL PresenterPaneBorderPainter::paintBorder (
199 const OUString& rsPaneBorderStyleName,
200 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
201 const css::awt::Rectangle& rOuterBorderRectangle,
202 const css::awt::Rectangle& rRepaintArea,
203 const OUString& rsTitle)
204 throw(css::uno::RuntimeException, std::exception)
206 ThrowIfDisposed();
208 // Early reject paints completely outside the repaint area.
209 if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
210 || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
211 || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
212 || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
214 return;
216 ProvideTheme(rxCanvas);
218 if (mpRenderer.get() != NULL)
220 mpRenderer->SetCanvas(rxCanvas);
221 mpRenderer->SetupClipping(
222 rRepaintArea,
223 rOuterBorderRectangle,
224 rsPaneBorderStyleName);
225 mpRenderer->PaintBorder(
226 rsTitle,
227 rOuterBorderRectangle,
228 rRepaintArea,
229 rsPaneBorderStyleName);
233 void SAL_CALL PresenterPaneBorderPainter::paintBorderWithCallout (
234 const OUString& rsPaneBorderStyleName,
235 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
236 const css::awt::Rectangle& rOuterBorderRectangle,
237 const css::awt::Rectangle& rRepaintArea,
238 const OUString& rsTitle,
239 const css::awt::Point& rCalloutAnchor)
240 throw(css::uno::RuntimeException, std::exception)
242 ThrowIfDisposed();
244 // Early reject paints completely outside the repaint area.
245 if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
246 || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
247 || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
248 || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
250 return;
252 ProvideTheme(rxCanvas);
254 if (mpRenderer.get() != NULL)
256 mpRenderer->SetCanvas(rxCanvas);
257 mpRenderer->SetupClipping(
258 rRepaintArea,
259 rOuterBorderRectangle,
260 rsPaneBorderStyleName);
261 mpRenderer->SetCalloutAnchor(rCalloutAnchor);
262 mpRenderer->PaintBorder(
263 rsTitle,
264 rOuterBorderRectangle,
265 rRepaintArea,
266 rsPaneBorderStyleName);
270 awt::Point SAL_CALL PresenterPaneBorderPainter::getCalloutOffset (
271 const OUString& rsPaneBorderStyleName)
272 throw(css::uno::RuntimeException, std::exception)
274 ThrowIfDisposed();
275 ProvideTheme();
276 if (mpRenderer.get() != NULL)
278 const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(
279 mpRenderer->GetRendererPaneStyle(rsPaneBorderStyleName));
280 if (pRendererPaneStyle.get() != NULL
281 && pRendererPaneStyle->mpBottomCallout.get() != NULL)
283 return awt::Point (
285 pRendererPaneStyle->mpBottomCallout->mnHeight
286 - pRendererPaneStyle->mpBottomCallout->mnYHotSpot);
290 return awt::Point(0,0);
295 bool PresenterPaneBorderPainter::ProvideTheme (const Reference<rendering::XCanvas>& rxCanvas)
297 bool bModified (false);
299 if ( ! mxContext.is())
300 return false;
302 if (mpTheme.get() != NULL)
304 // Check if the theme already has a canvas.
305 if ( ! mpTheme->HasCanvas())
307 mpTheme->ProvideCanvas(rxCanvas);
308 bModified = true;
311 else
313 mpTheme.reset(new PresenterTheme(mxContext, OUString(), rxCanvas));
314 bModified = true;
317 if (mpTheme.get() != NULL && bModified)
319 if (mpRenderer.get() == NULL)
320 mpRenderer.reset(new Renderer(mxContext, mpTheme));
321 else
322 mpRenderer->SetCanvas(rxCanvas);
325 return bModified;
328 bool PresenterPaneBorderPainter::ProvideTheme()
330 if (mpTheme.get() == NULL)
332 // Create a theme without bitmaps (no canvas => no bitmaps).
333 return ProvideTheme(NULL);
335 else
337 // When there already is a theme then without a canvas we can not
338 // add anything new.
339 return false;
343 void PresenterPaneBorderPainter::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
345 mpTheme = rpTheme;
346 if (mpRenderer.get() == NULL)
347 mpRenderer.reset(new Renderer(mxContext, mpTheme));
350 awt::Rectangle PresenterPaneBorderPainter::AddBorder (
351 const OUString& rsPaneURL,
352 const awt::Rectangle& rInnerBox,
353 const css::drawing::framework::BorderType eBorderType) const
355 if (mpRenderer.get() != NULL)
357 const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
358 if (pRendererPaneStyle.get() != NULL)
359 return pRendererPaneStyle->AddBorder(rInnerBox, eBorderType);
361 return rInnerBox;
364 awt::Rectangle PresenterPaneBorderPainter::RemoveBorder (
365 const OUString& rsPaneURL,
366 const css::awt::Rectangle& rOuterBox,
367 const css::drawing::framework::BorderType eBorderType) const
369 if (mpRenderer.get() != NULL)
371 const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
372 if (pRendererPaneStyle.get() != NULL)
373 return pRendererPaneStyle->RemoveBorder(rOuterBox, eBorderType);
375 return rOuterBox;
378 void PresenterPaneBorderPainter::ThrowIfDisposed() const
379 throw (::com::sun::star::lang::DisposedException)
381 if (rBHelper.bDisposed || rBHelper.bInDispose)
383 throw lang::DisposedException (
384 OUString(
385 "PresenterPaneBorderPainter object has already been disposed"),
386 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
390 //===== PresenterPaneBorderPainter::Renderer =====================================
392 PresenterPaneBorderPainter::Renderer::Renderer (
393 const Reference<XComponentContext>& rxContext,
394 const ::boost::shared_ptr<PresenterTheme>& rpTheme)
395 : mpTheme(rpTheme),
396 maRendererPaneStyles(),
397 mxCanvas(),
398 mxPresenterHelper(),
399 maViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
400 mxViewStateClip(),
401 mbHasCallout(false),
402 maCalloutAnchor()
404 (void)rxContext;
406 Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
407 if (xFactory.is())
409 mxPresenterHelper = Reference<drawing::XPresenterHelper>(
410 xFactory->createInstanceWithContext(
411 OUString("com.sun.star.comp.Draw.PresenterHelper"),
412 rxContext),
413 UNO_QUERY_THROW);
417 PresenterPaneBorderPainter::Renderer::~Renderer()
421 void PresenterPaneBorderPainter::Renderer::SetCanvas (const Reference<rendering::XCanvas>& rxCanvas)
423 if (mxCanvas != rxCanvas)
425 mxCanvas = rxCanvas;
429 void PresenterPaneBorderPainter::Renderer::PaintBorder (
430 const OUString& rsTitle,
431 const awt::Rectangle& rBBox,
432 const awt::Rectangle& rUpdateBox,
433 const OUString& rsPaneURL)
435 if ( ! mxCanvas.is())
436 return;
438 // Create the outer and inner border of the, ahm, border.
439 ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneURL));
440 if (pStyle.get() == NULL)
441 return;
443 awt::Rectangle aOuterBox (rBBox);
444 awt::Rectangle aCenterBox (
445 pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_OUTER_BORDER));
446 awt::Rectangle aInnerBox (
447 pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
449 // Prepare references for all used bitmaps.
450 SharedBitmapDescriptor pTop (pStyle->mpTop);
451 SharedBitmapDescriptor pTopLeft (pStyle->mpTopLeft);
452 SharedBitmapDescriptor pTopRight (pStyle->mpTopRight);
453 SharedBitmapDescriptor pLeft (pStyle->mpLeft);
454 SharedBitmapDescriptor pRight (pStyle->mpRight);
455 SharedBitmapDescriptor pBottomLeft (pStyle->mpBottomLeft);
456 SharedBitmapDescriptor pBottomRight (pStyle->mpBottomRight);
457 SharedBitmapDescriptor pBottom (pStyle->mpBottom);
458 SharedBitmapDescriptor pBackground (pStyle->mpBackground);
460 // Paint the sides.
461 PaintBitmap(aCenterBox, rUpdateBox, 0,-1,
462 pTopLeft->mnXOffset, pTopRight->mnXOffset, true, pTop, pBackground);
463 PaintBitmap(aCenterBox, rUpdateBox, -1,0,
464 pTopLeft->mnYOffset, pBottomLeft->mnYOffset, true, pLeft, pBackground);
465 PaintBitmap(aCenterBox, rUpdateBox, +1,0,
466 pTopRight->mnYOffset, pBottomRight->mnYOffset, true, pRight, pBackground);
467 if (mbHasCallout && pStyle->mpBottomCallout->GetNormalBitmap().is())
469 const sal_Int32 nCalloutWidth (pStyle->mpBottomCallout->mnWidth);
470 sal_Int32 nCalloutX (maCalloutAnchor.X - pStyle->mpBottomCallout->mnXHotSpot
471 - (aCenterBox.X - aOuterBox.X));
472 if (nCalloutX < pBottomLeft->mnXOffset + aCenterBox.X)
473 nCalloutX = pBottomLeft->mnXOffset + aCenterBox.X;
474 if (nCalloutX > pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width)
475 nCalloutX = pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width;
476 // Paint bottom callout.
477 PaintBitmap(aCenterBox, rUpdateBox, 0,+1, nCalloutX,0, false, pStyle->mpBottomCallout, pBackground);
478 // Paint regular bottom bitmap left and right.
479 PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
480 pBottomLeft->mnXOffset, nCalloutX-aCenterBox.Width, true, pBottom, pBackground);
481 PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
482 nCalloutX+nCalloutWidth, pBottomRight->mnXOffset, true, pBottom, pBackground);
484 else
486 // Stretch the bottom bitmap over the full width.
487 PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
488 pBottomLeft->mnXOffset, pBottomRight->mnXOffset, true, pBottom, pBackground);
491 // Paint the corners.
492 PaintBitmap(aCenterBox, rUpdateBox, -1,-1, 0,0, false, pTopLeft, pBackground);
493 PaintBitmap(aCenterBox, rUpdateBox, +1,-1, 0,0, false, pTopRight, pBackground);
494 PaintBitmap(aCenterBox, rUpdateBox, -1,+1, 0,0, false, pBottomLeft, pBackground);
495 PaintBitmap(aCenterBox, rUpdateBox, +1,+1, 0,0, false, pBottomRight, pBackground);
497 // Paint the title.
498 PaintTitle(rsTitle, pStyle, rUpdateBox, aOuterBox, aInnerBox, false);
500 // In a double buffering environment request to make the changes visible.
501 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
502 if (xSpriteCanvas.is())
503 xSpriteCanvas->updateScreen(sal_False);
506 void PresenterPaneBorderPainter::Renderer::PaintTitle (
507 const OUString& rsTitle,
508 const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
509 const awt::Rectangle& rUpdateBox,
510 const awt::Rectangle& rOuterBox,
511 const awt::Rectangle& rInnerBox,
512 bool bPaintBackground)
514 if ( ! mxCanvas.is())
515 return;
517 if (rsTitle.isEmpty())
518 return;
520 Reference<rendering::XCanvasFont> xFont (rpStyle->GetFont(mxCanvas));
521 if ( ! xFont.is())
522 return;
524 rendering::StringContext aContext (
525 rsTitle,
527 rsTitle.getLength());
528 Reference<rendering::XTextLayout> xLayout (xFont->createTextLayout(
529 aContext,
530 rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
531 0));
532 if ( ! xLayout.is())
533 return;
535 /// this is responsible of the texts above the slide windows
536 geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
537 const double nTextHeight = aBox.Y2 - aBox.Y1;
538 const double nTextWidth = aBox.X1 + aBox.X2;
539 double nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
540 const sal_Int32 nTitleBarHeight = rInnerBox.Y - rOuterBox.Y - 1;
541 double nY = rOuterBox.Y + (nTitleBarHeight - nTextHeight) / 2 - aBox.Y1;
542 if (nY >= rInnerBox.Y)
543 nY = rInnerBox.Y - 1;
544 switch (rpStyle->meFontAnchor)
546 default:
547 case RendererPaneStyle::AnchorLeft:
548 nX = rInnerBox.X;
549 break;
550 case RendererPaneStyle::AnchorRight:
551 nX = rInnerBox.X + rInnerBox.Width - nTextWidth;
552 break;
553 case RendererPaneStyle::AnchorCenter:
554 nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
555 break;
557 nX += rpStyle->mnFontXOffset;
558 nY += rpStyle->mnFontYOffset;
560 if (rUpdateBox.X >= nX+nTextWidth
561 || rUpdateBox.Y >= nY+nTextHeight
562 || rUpdateBox.X+rUpdateBox.Width <= nX
563 || rUpdateBox.Y+rUpdateBox.Height <= nY)
565 return;
568 rendering::RenderState aRenderState(
569 geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
570 NULL,
571 Sequence<double>(4),
572 rendering::CompositeOperation::SOURCE);
574 if (bPaintBackground)
576 PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
577 Sequence<Sequence<geometry::RealPoint2D> > aPolygons(1);
578 aPolygons[0] = Sequence<geometry::RealPoint2D>(4);
579 aPolygons[0][0] = geometry::RealPoint2D(0, -nTextHeight);
580 aPolygons[0][1] = geometry::RealPoint2D(0, 0);
581 aPolygons[0][2] = geometry::RealPoint2D(nTextWidth, 0);
582 aPolygons[0][3] = geometry::RealPoint2D(nTextWidth, -nTextHeight);
583 Reference<rendering::XPolyPolygon2D> xPolygon (
584 mxCanvas->getDevice()->createCompatibleLinePolyPolygon(aPolygons), UNO_QUERY);
585 if (xPolygon.is())
586 xPolygon->setClosed(0, sal_True);
587 mxCanvas->fillPolyPolygon(
588 xPolygon,
589 maViewState,
590 aRenderState);
592 else
594 PresenterCanvasHelper::SetDeviceColor(
595 aRenderState,
596 rpStyle->mpFont->mnColor);
598 mxCanvas->drawTextLayout (
599 xLayout,
600 maViewState,
601 aRenderState);
605 ::boost::shared_ptr<RendererPaneStyle>
606 PresenterPaneBorderPainter::Renderer::GetRendererPaneStyle (const OUString& rsResourceURL)
608 OSL_ASSERT(mpTheme.get()!=NULL);
610 RendererPaneStyleContainer::const_iterator iStyle (maRendererPaneStyles.find(rsResourceURL));
611 if (iStyle == maRendererPaneStyles.end())
613 OUString sPaneStyleName ("DefaultRendererPaneStyle");
615 // Get pane layout name for resource URL.
616 const OUString sStyleName (mpTheme->GetStyleName(rsResourceURL));
617 if (!sStyleName.isEmpty())
618 sPaneStyleName = sStyleName;
620 // Create a new pane style object and initialize it with bitmaps.
621 ::boost::shared_ptr<RendererPaneStyle> pStyle (
622 new RendererPaneStyle(mpTheme,sPaneStyleName));
623 iStyle = maRendererPaneStyles.insert(
624 RendererPaneStyleContainer::value_type(rsResourceURL, pStyle)).first;
626 if (iStyle != maRendererPaneStyles.end())
627 return iStyle->second;
628 else
629 return ::boost::shared_ptr<RendererPaneStyle>();
632 void PresenterPaneBorderPainter::Renderer::SetCalloutAnchor (
633 const awt::Point& rCalloutAnchor)
635 mbHasCallout = true;
636 maCalloutAnchor = rCalloutAnchor;
639 void PresenterPaneBorderPainter::Renderer::PaintBitmap(
640 const awt::Rectangle& rBox,
641 const awt::Rectangle& rUpdateBox,
642 const sal_Int32 nXPosition,
643 const sal_Int32 nYPosition,
644 const sal_Int32 nStartOffset,
645 const sal_Int32 nEndOffset,
646 const bool bExpand,
647 const SharedBitmapDescriptor& rpBitmap,
648 const SharedBitmapDescriptor& rpBackgroundBitmap)
650 (void)rpBackgroundBitmap;
652 bool bUseCanvas (mxCanvas.is());
653 if ( ! bUseCanvas)
654 return;
656 if (rpBitmap->mnWidth<=0 || rpBitmap->mnHeight<=0)
657 return;
659 Reference<rendering::XBitmap> xBitmap (rpBitmap->GetNormalBitmap(), UNO_QUERY);
660 if ( ! xBitmap.is())
661 return;
663 // Calculate position, and for side bitmaps, the size.
664 sal_Int32 nX = 0;
665 sal_Int32 nY = 0;
666 sal_Int32 nW = rpBitmap->mnWidth;
667 sal_Int32 nH = rpBitmap->mnHeight;
668 if (nXPosition < 0)
670 nX = rBox.X - rpBitmap->mnWidth + rpBitmap->mnXOffset;
672 else if (nXPosition > 0)
674 nX = rBox.X + rBox.Width + rpBitmap->mnXOffset;
676 else
678 nX = rBox.X + nStartOffset;
679 if (bExpand)
680 nW = rBox.Width - nStartOffset + nEndOffset;
683 if (nYPosition < 0)
685 nY = rBox.Y - rpBitmap->mnHeight + rpBitmap->mnYOffset;
687 else if (nYPosition > 0)
689 nY = rBox.Y + rBox.Height + rpBitmap->mnYOffset;
691 else
693 nY = rBox.Y + nStartOffset;
694 if (bExpand)
695 nH = rBox.Height - nStartOffset + nEndOffset;
698 // Do not paint when bitmap area does not intersect with update box.
699 if (nX >= rUpdateBox.X + rUpdateBox.Width
700 || nX+nW <= rUpdateBox.X
701 || nY >= rUpdateBox.Y + rUpdateBox.Height
702 || nY+nH <= rUpdateBox.Y)
704 return;
708 Reference<rendering::XBitmap> xMaskedBitmap (
709 PresenterBitmapHelper::FillMaskedWithColor (
710 mxCanvas,
711 Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
712 rBitmap.mxMaskBitmap,
713 0x00ff0000,
714 rBackgroundBitmap.maReplacementColor));
715 if (xMaskedBitmap.is())
716 xBitmap = xMaskedBitmap;
717 else if (rBitmap.mxMaskBitmap.is() && mxPresenterHelper.is())
719 const static sal_Int32 nOutsideMaskColor (0x00ff0000);
720 Reference<rendering::XIntegerBitmap> xMask (
721 mxPresenterHelper->createMask(
722 mxCanvas,
723 rBitmap.mxMaskBitmap,
724 nOutsideMaskColor,
725 false));
726 xBitmap = mxPresenterHelper->applyBitmapMaskWithColor(
727 mxCanvas,
728 Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
729 xMask,
730 rBackgroundBitmap.maReplacementColor);
733 rendering::RenderState aRenderState (
734 geometry::AffineMatrix2D(
735 double(nW)/rpBitmap->mnWidth, 0, nX,
736 0, double(nH)/rpBitmap->mnHeight, nY),
737 NULL,
738 Sequence<double>(4),
739 rendering::CompositeOperation::OVER);
741 if (xBitmap.is())
742 mxCanvas->drawBitmap(
743 xBitmap,
744 maViewState,
745 aRenderState);
748 void PresenterPaneBorderPainter::Renderer::SetupClipping (
749 const awt::Rectangle& rUpdateBox,
750 const awt::Rectangle& rOuterBox,
751 const OUString& rsPaneStyleName)
753 mxViewStateClip = NULL;
754 maViewState.Clip = NULL;
756 if ( ! mxCanvas.is())
757 return;
759 ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneStyleName));
760 if (pStyle.get() == NULL)
762 mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
763 rUpdateBox,
764 mxCanvas->getDevice());
766 else
768 awt::Rectangle aInnerBox (
769 pStyle->RemoveBorder(rOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
770 ::std::vector<awt::Rectangle> aRectangles;
771 aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, rOuterBox));
772 aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, aInnerBox));
773 mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
774 aRectangles,
775 mxCanvas->getDevice());
776 if (mxViewStateClip.is())
777 mxViewStateClip->setFillRule(rendering::FillRule_EVEN_ODD);
779 maViewState.Clip = mxViewStateClip;
782 namespace {
784 //===== BorderSize ============================================================
786 BorderSize::BorderSize()
787 : mnLeft(0),
788 mnTop(0),
789 mnRight(0),
790 mnBottom(0)
794 //===== RendererPaneStyle ============================================================
796 RendererPaneStyle::RendererPaneStyle (
797 const ::boost::shared_ptr<PresenterTheme>& rpTheme,
798 const OUString& rsStyleName)
799 : mpTopLeft(),
800 mpTop(),
801 mpTopRight(),
802 mpLeft(),
803 mpRight(),
804 mpBottomLeft(),
805 mpBottom(),
806 mpBottomRight(),
807 mpBottomCallout(),
808 mpBackground(),
809 mpEmpty(new PresenterBitmapDescriptor()),
810 mpFont(),
811 mnFontXOffset(0),
812 mnFontYOffset(0),
813 meFontAnchor(AnchorCenter),
814 maInnerBorderSize(),
815 maOuterBorderSize(),
816 maTotalBorderSize()
818 if (rpTheme.get() != NULL)
820 mpTopLeft = GetBitmap(rpTheme, rsStyleName, "TopLeft");
821 mpTop = GetBitmap(rpTheme, rsStyleName, "Top");
822 mpTopRight = GetBitmap(rpTheme, rsStyleName, "TopRight");
823 mpLeft = GetBitmap(rpTheme, rsStyleName,"Left");
824 mpRight = GetBitmap(rpTheme, rsStyleName, "Right");
825 mpBottomLeft = GetBitmap(rpTheme, rsStyleName, "BottomLeft");
826 mpBottom = GetBitmap(rpTheme, rsStyleName, "Bottom");
827 mpBottomRight = GetBitmap(rpTheme, rsStyleName, "BottomRight");
828 mpBottomCallout = GetBitmap(rpTheme, rsStyleName, "BottomCallout");
829 mpBackground = GetBitmap(rpTheme, OUString(), "Background");
831 // Get font description.
832 mpFont = rpTheme->GetFont(rsStyleName);
834 OUString sAnchor ("Left");
835 if (mpFont.get() != NULL)
837 sAnchor = mpFont->msAnchor;
838 mnFontXOffset = mpFont->mnXOffset;
839 mnFontYOffset = mpFont->mnYOffset;
842 if ( sAnchor == "Left" )
843 meFontAnchor = AnchorLeft;
844 else if ( sAnchor == "Right" )
845 meFontAnchor = AnchorRight;
846 else
847 meFontAnchor = AnchorCenter;
849 // Get border sizes.
852 ::std::vector<sal_Int32> aInnerBorder (rpTheme->GetBorderSize(rsStyleName, false));
853 OSL_ASSERT(aInnerBorder.size()==4);
854 maInnerBorderSize.mnLeft = aInnerBorder[0];
855 maInnerBorderSize.mnTop = aInnerBorder[1];
856 maInnerBorderSize.mnRight = aInnerBorder[2];
857 maInnerBorderSize.mnBottom = aInnerBorder[3];
859 ::std::vector<sal_Int32> aOuterBorder (rpTheme->GetBorderSize(rsStyleName, true));
860 OSL_ASSERT(aOuterBorder.size()==4);
861 maOuterBorderSize.mnLeft = aOuterBorder[0];
862 maOuterBorderSize.mnTop = aOuterBorder[1];
863 maOuterBorderSize.mnRight = aOuterBorder[2];
864 maOuterBorderSize.mnBottom = aOuterBorder[3];
866 catch(beans::UnknownPropertyException&)
868 OSL_ASSERT(false);
871 UpdateBorderSizes();
875 awt::Rectangle RendererPaneStyle::AddBorder (
876 const awt::Rectangle& rBox,
877 const drawing::framework::BorderType eBorderType) const
879 const BorderSize* pBorderSize = NULL;
880 switch (eBorderType)
882 case drawing::framework::BorderType_INNER_BORDER:
883 pBorderSize = &maInnerBorderSize;
884 break;
885 case drawing::framework::BorderType_OUTER_BORDER:
886 pBorderSize = &maOuterBorderSize;
887 break;
888 case drawing::framework::BorderType_TOTAL_BORDER:
889 pBorderSize = &maTotalBorderSize;
890 break;
891 default:
892 return rBox;
894 return awt::Rectangle (
895 rBox.X - pBorderSize->mnLeft,
896 rBox.Y - pBorderSize->mnTop,
897 rBox.Width + pBorderSize->mnLeft + pBorderSize->mnRight,
898 rBox.Height + pBorderSize->mnTop + pBorderSize->mnBottom);
901 awt::Rectangle RendererPaneStyle::RemoveBorder (
902 const awt::Rectangle& rBox,
903 const css::drawing::framework::BorderType eBorderType) const
905 const BorderSize* pBorderSize = NULL;
906 switch (eBorderType)
908 case drawing::framework::BorderType_INNER_BORDER:
909 pBorderSize = &maInnerBorderSize;
910 break;
911 case drawing::framework::BorderType_OUTER_BORDER:
912 pBorderSize = &maOuterBorderSize;
913 break;
914 case drawing::framework::BorderType_TOTAL_BORDER:
915 pBorderSize = &maTotalBorderSize;
916 break;
917 default:
918 return rBox;
920 return awt::Rectangle (
921 rBox.X + pBorderSize->mnLeft,
922 rBox.Y + pBorderSize->mnTop,
923 rBox.Width - pBorderSize->mnLeft - pBorderSize->mnRight,
924 rBox.Height - pBorderSize->mnTop - pBorderSize->mnBottom);
927 const Reference<rendering::XCanvasFont> RendererPaneStyle::GetFont (
928 const Reference<rendering::XCanvas>& rxCanvas) const
930 if (mpFont.get() != NULL)
931 mpFont->PrepareFont(rxCanvas);
932 return mpFont->mxFont;
935 void RendererPaneStyle::UpdateBorderSizes()
937 maTotalBorderSize.mnLeft = maInnerBorderSize.mnLeft + maOuterBorderSize.mnLeft;
938 maTotalBorderSize.mnTop = maInnerBorderSize.mnTop + maOuterBorderSize.mnTop;
939 maTotalBorderSize.mnRight = maInnerBorderSize.mnRight + maOuterBorderSize.mnRight;
940 maTotalBorderSize.mnBottom = maInnerBorderSize.mnBottom + maOuterBorderSize.mnBottom;
943 SharedBitmapDescriptor RendererPaneStyle::GetBitmap(
944 const ::boost::shared_ptr<PresenterTheme>& rpTheme,
945 const OUString& rsStyleName,
946 const OUString& rsBitmapName)
948 SharedBitmapDescriptor pDescriptor (rpTheme->GetBitmap(rsStyleName, rsBitmapName));
949 if (pDescriptor.get() != NULL)
950 return pDescriptor;
951 else
952 return mpEmpty;
955 } // end of anonymous namespace
957 } } // end of namespace ::sd::presenter
959 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */