merge the formfield patch from ooo-build
[ooovba.git] / sdext / source / presenter / PresenterPaneBorderPainter.cxx
blob38c0a1c727943aed81584fbaff02bc305f1bcca6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterPaneBorderPainter.cxx,v $
11 * $Revision: 1.6 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sdext.hxx"
35 #include "PresenterPaneBorderPainter.hxx"
36 #include "PresenterCanvasHelper.hxx"
37 #include "PresenterConfigurationAccess.hxx"
38 #include "PresenterGeometryHelper.hxx"
39 #include "PresenterTheme.hxx"
40 #include <com/sun/star/awt/FontDescriptor.hpp>
41 #include <com/sun/star/awt/Point.hpp>
42 #include <com/sun/star/awt/Rectangle.hpp>
43 #include <com/sun/star/awt/SimpleFontMetric.hpp>
44 #include <com/sun/star/awt/XFont.hpp>
45 #include <com/sun/star/drawing/XPresenterHelper.hpp>
46 #include <com/sun/star/graphic/XGraphic.hpp>
47 #include <com/sun/star/graphic/XGraphicRenderer.hpp>
48 #include <com/sun/star/rendering/CompositeOperation.hpp>
49 #include <com/sun/star/rendering/FillRule.hpp>
50 #include <com/sun/star/rendering/TextDirection.hpp>
51 #include <com/sun/star/rendering/XIntegerBitmap.hpp>
52 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
53 #include <map>
54 #include <vector>
55 #include <boost/shared_ptr.hpp>
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
59 using ::rtl::OUString;
61 #define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)))
63 namespace sdext { namespace presenter {
65 namespace {
66 class BorderSize
68 public:
69 BorderSize (void);
70 BorderSize (const BorderSize& rBorderSize);
71 BorderSize& operator= (const BorderSize& rBoderSize);
72 sal_Int32 mnLeft;
73 sal_Int32 mnTop;
74 sal_Int32 mnRight;
75 sal_Int32 mnBottom;
78 class RendererPaneStyle
80 public:
81 RendererPaneStyle (
82 const ::boost::shared_ptr<PresenterTheme>& rpTheme,
83 const OUString& rsStyleName);
85 awt::Rectangle AddBorder (
86 const awt::Rectangle& rBox,
87 drawing::framework::BorderType eBorderType) const;
88 awt::Rectangle RemoveBorder (
89 const awt::Rectangle& rBox,
90 drawing::framework::BorderType eBorderType) const;
91 const Reference<rendering::XCanvasFont> GetFont (
92 const Reference<rendering::XCanvas>& rxCanvas) const;
94 SharedBitmapDescriptor mpTopLeft;
95 SharedBitmapDescriptor mpTop;
96 SharedBitmapDescriptor mpTopRight;
97 SharedBitmapDescriptor mpLeft;
98 SharedBitmapDescriptor mpRight;
99 SharedBitmapDescriptor mpBottomLeft;
100 SharedBitmapDescriptor mpBottom;
101 SharedBitmapDescriptor mpBottomRight;
102 SharedBitmapDescriptor mpBottomCallout;
103 SharedBitmapDescriptor mpBackground;
104 SharedBitmapDescriptor mpEmpty;
105 PresenterTheme::SharedFontDescriptor mpFont;
106 sal_Int32 mnFontXOffset;
107 sal_Int32 mnFontYOffset;
108 enum Anchor { AnchorLeft, AnchorRight, AnchorCenter } meFontAnchor;
109 BorderSize maInnerBorderSize;
110 BorderSize maOuterBorderSize;
111 BorderSize maTotalBorderSize;
112 enum Side { Left, Top, Right, Bottom };
113 private:
114 void UpdateBorderSizes (void);
115 SharedBitmapDescriptor GetBitmap(
116 const ::boost::shared_ptr<PresenterTheme>& rpTheme,
117 const OUString& rsStyleName,
118 const OUString& rsBitmapName);
124 class PresenterPaneBorderPainter::Renderer
126 public:
127 Renderer (
128 const Reference<XComponentContext>& rxContext,
129 const ::boost::shared_ptr<PresenterTheme>& rpTheme);
130 ~Renderer (void);
132 void SetCanvas (const Reference<rendering::XCanvas>& rxCanvas);
133 void PaintBorder (
134 const OUString& rsTitle,
135 const awt::Rectangle& rBBox,
136 const awt::Rectangle& rUpdateBox,
137 const OUString& rsPaneURL);
138 void PaintTitle (
139 const OUString& rsTitle,
140 const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
141 const awt::Rectangle& rUpdateBox,
142 const awt::Rectangle& rOuterBox,
143 const awt::Rectangle& rInnerBox,
144 const bool bPaintBackground);
145 void SetupClipping (
146 const awt::Rectangle& rUpdateBox,
147 const awt::Rectangle& rOuterBox,
148 const OUString& rsPaneStyleName);
149 ::boost::shared_ptr<RendererPaneStyle> GetRendererPaneStyle (const OUString& rsResourceURL);
150 void SetCalloutAnchor (
151 const awt::Point& rCalloutAnchor);
153 private:
154 ::boost::shared_ptr<PresenterTheme> mpTheme;
155 typedef ::std::map<OUString, ::boost::shared_ptr<RendererPaneStyle> > RendererPaneStyleContainer;
156 RendererPaneStyleContainer maRendererPaneStyles;
157 Reference<rendering::XCanvas> mxCanvas;
158 Reference<drawing::XPresenterHelper> mxPresenterHelper;
159 css::rendering::ViewState maViewState;
160 Reference<rendering::XPolyPolygon2D> mxViewStateClip;
161 bool mbHasCallout;
162 awt::Point maCalloutAnchor;
164 void PaintBitmap(
165 const awt::Rectangle& rBox,
166 const awt::Rectangle& rUpdateBox,
167 const sal_Int32 nXPosition,
168 const sal_Int32 nYPosition,
169 const sal_Int32 nStartOffset,
170 const sal_Int32 nEndOffset,
171 const bool bExpand,
172 const SharedBitmapDescriptor& rpBitmap,
173 const SharedBitmapDescriptor& rpBackgroundBitmap);
179 // ===== PresenterPaneBorderPainter ===========================================
181 PresenterPaneBorderPainter::PresenterPaneBorderPainter (
182 const Reference<XComponentContext>& rxContext)
183 : PresenterPaneBorderPainterInterfaceBase(m_aMutex),
184 mxContext(rxContext),
185 mpTheme(),
186 mpRenderer()
193 PresenterPaneBorderPainter::~PresenterPaneBorderPainter (void)
200 //----- XPaneBorderPainter ----------------------------------------------------
202 awt::Rectangle SAL_CALL PresenterPaneBorderPainter::addBorder (
203 const rtl::OUString& rsPaneBorderStyleName,
204 const css::awt::Rectangle& rRectangle,
205 drawing::framework::BorderType eBorderType)
206 throw(css::uno::RuntimeException)
208 ThrowIfDisposed();
210 ProvideTheme();
212 return AddBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
218 awt::Rectangle SAL_CALL PresenterPaneBorderPainter::removeBorder (
219 const rtl::OUString& rsPaneBorderStyleName,
220 const css::awt::Rectangle& rRectangle,
221 drawing::framework::BorderType eBorderType)
222 throw(css::uno::RuntimeException)
224 ThrowIfDisposed();
226 ProvideTheme();
228 return RemoveBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
234 void SAL_CALL PresenterPaneBorderPainter::paintBorder (
235 const rtl::OUString& rsPaneBorderStyleName,
236 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
237 const css::awt::Rectangle& rOuterBorderRectangle,
238 const css::awt::Rectangle& rRepaintArea,
239 const rtl::OUString& rsTitle)
240 throw(css::uno::RuntimeException)
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->PaintBorder(
262 rsTitle,
263 rOuterBorderRectangle,
264 rRepaintArea,
265 rsPaneBorderStyleName);
272 void SAL_CALL PresenterPaneBorderPainter::paintBorderWithCallout (
273 const rtl::OUString& rsPaneBorderStyleName,
274 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
275 const css::awt::Rectangle& rOuterBorderRectangle,
276 const css::awt::Rectangle& rRepaintArea,
277 const rtl::OUString& rsTitle,
278 const css::awt::Point& rCalloutAnchor)
279 throw(css::uno::RuntimeException)
281 ThrowIfDisposed();
283 // Early reject paints completely outside the repaint area.
284 if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
285 || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
286 || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
287 || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
289 return;
291 ProvideTheme(rxCanvas);
293 if (mpRenderer.get() != NULL)
295 mpRenderer->SetCanvas(rxCanvas);
296 mpRenderer->SetupClipping(
297 rRepaintArea,
298 rOuterBorderRectangle,
299 rsPaneBorderStyleName);
300 mpRenderer->SetCalloutAnchor(rCalloutAnchor);
301 mpRenderer->PaintBorder(
302 rsTitle,
303 rOuterBorderRectangle,
304 rRepaintArea,
305 rsPaneBorderStyleName);
312 awt::Point SAL_CALL PresenterPaneBorderPainter::getCalloutOffset (
313 const rtl::OUString& rsPaneBorderStyleName)
314 throw(css::uno::RuntimeException)
316 ThrowIfDisposed();
317 ProvideTheme();
318 if (mpRenderer.get() != NULL)
320 const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(
321 mpRenderer->GetRendererPaneStyle(rsPaneBorderStyleName));
322 if (pRendererPaneStyle.get() != NULL
323 && pRendererPaneStyle->mpBottomCallout.get() != NULL)
325 return awt::Point (
327 pRendererPaneStyle->mpBottomCallout->mnHeight
328 - pRendererPaneStyle->mpBottomCallout->mnYHotSpot);
332 return awt::Point(0,0);
338 //-----------------------------------------------------------------------------
340 bool PresenterPaneBorderPainter::ProvideTheme (const Reference<rendering::XCanvas>& rxCanvas)
342 bool bModified (false);
344 if ( ! mxContext.is())
345 return false;
347 if (mpTheme.get() != NULL)
349 // Check if the theme already has a canvas.
350 if ( ! mpTheme->HasCanvas())
352 mpTheme->ProvideCanvas(rxCanvas);
353 bModified = true;
356 else
358 mpTheme.reset(new PresenterTheme(mxContext, OUString(), rxCanvas));
359 bModified = true;
362 if (mpTheme.get() != NULL && bModified)
364 if (mpRenderer.get() == NULL)
365 mpRenderer.reset(new Renderer(mxContext, mpTheme));
366 else
367 mpRenderer->SetCanvas(rxCanvas);
370 return bModified;
376 bool PresenterPaneBorderPainter::ProvideTheme (void)
378 if (mpTheme.get() == NULL)
380 // Create a theme without bitmaps (no canvas => no bitmaps).
381 return ProvideTheme(NULL);
383 else
385 // When there already is a theme then without a canvas we can not
386 // add anything new.
387 return false;
394 bool PresenterPaneBorderPainter::HasTheme (void) const
396 return mpTheme.get()!=NULL && mpRenderer.get()!=NULL;
402 void PresenterPaneBorderPainter::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
404 mpTheme = rpTheme;
405 if (mpRenderer.get() == NULL)
406 mpRenderer.reset(new Renderer(mxContext, mpTheme));
412 awt::Rectangle PresenterPaneBorderPainter::AddBorder (
413 const ::rtl::OUString& rsPaneURL,
414 const awt::Rectangle& rInnerBox,
415 const css::drawing::framework::BorderType eBorderType) const
417 if (mpRenderer.get() != NULL)
419 const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
420 if (pRendererPaneStyle.get() != NULL)
421 return pRendererPaneStyle->AddBorder(rInnerBox, eBorderType);
423 return rInnerBox;
429 awt::Rectangle PresenterPaneBorderPainter::RemoveBorder (
430 const ::rtl::OUString& rsPaneURL,
431 const css::awt::Rectangle& rOuterBox,
432 const css::drawing::framework::BorderType eBorderType) const
434 if (mpRenderer.get() != NULL)
436 const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
437 if (pRendererPaneStyle.get() != NULL)
438 return pRendererPaneStyle->RemoveBorder(rOuterBox, eBorderType);
440 return rOuterBox;
446 void PresenterPaneBorderPainter::ThrowIfDisposed (void) const
447 throw (::com::sun::star::lang::DisposedException)
449 if (rBHelper.bDisposed || rBHelper.bInDispose)
451 throw lang::DisposedException (
452 OUString(RTL_CONSTASCII_USTRINGPARAM(
453 "PresenterPaneBorderPainter object has already been disposed")),
454 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
461 //===== PresenterPaneBorderPainter::Renderer =====================================
464 PresenterPaneBorderPainter::Renderer::Renderer (
465 const Reference<XComponentContext>& rxContext,
466 const ::boost::shared_ptr<PresenterTheme>& rpTheme)
467 : mpTheme(rpTheme),
468 maRendererPaneStyles(),
469 mxCanvas(),
470 mxPresenterHelper(),
471 maViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
472 mxViewStateClip(),
473 mbHasCallout(false),
474 maCalloutAnchor()
476 (void)rxContext;
478 Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
479 if (xFactory.is())
481 mxPresenterHelper = Reference<drawing::XPresenterHelper>(
482 xFactory->createInstanceWithContext(
483 OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"),
484 rxContext),
485 UNO_QUERY_THROW);
492 PresenterPaneBorderPainter::Renderer::~Renderer (void)
499 void PresenterPaneBorderPainter::Renderer::SetCanvas (const Reference<rendering::XCanvas>& rxCanvas)
501 if (mxCanvas != rxCanvas)
503 mxCanvas = rxCanvas;
510 void PresenterPaneBorderPainter::Renderer::PaintBorder (
511 const OUString& rsTitle,
512 const awt::Rectangle& rBBox,
513 const awt::Rectangle& rUpdateBox,
514 const OUString& rsPaneURL)
516 if ( ! mxCanvas.is())
517 return;
519 // Create the outer and inner border of the, ahm, border.
520 ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneURL));
521 if (pStyle.get() == NULL)
522 return;
524 awt::Rectangle aOuterBox (rBBox);
525 awt::Rectangle aCenterBox (
526 pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_OUTER_BORDER));
527 awt::Rectangle aInnerBox (
528 pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
530 // Prepare references for all used bitmaps.
531 SharedBitmapDescriptor pTop (pStyle->mpTop);
532 SharedBitmapDescriptor pTopLeft (pStyle->mpTopLeft);
533 SharedBitmapDescriptor pTopRight (pStyle->mpTopRight);
534 SharedBitmapDescriptor pLeft (pStyle->mpLeft);
535 SharedBitmapDescriptor pRight (pStyle->mpRight);
536 SharedBitmapDescriptor pBottomLeft (pStyle->mpBottomLeft);
537 SharedBitmapDescriptor pBottomRight (pStyle->mpBottomRight);
538 SharedBitmapDescriptor pBottom (pStyle->mpBottom);
539 SharedBitmapDescriptor pBackground (pStyle->mpBackground);
541 // Paint the sides.
542 PaintBitmap(aCenterBox, rUpdateBox, 0,-1,
543 pTopLeft->mnXOffset, pTopRight->mnXOffset, true, pTop, pBackground);
544 PaintBitmap(aCenterBox, rUpdateBox, -1,0,
545 pTopLeft->mnYOffset, pBottomLeft->mnYOffset, true, pLeft, pBackground);
546 PaintBitmap(aCenterBox, rUpdateBox, +1,0,
547 pTopRight->mnYOffset, pBottomRight->mnYOffset, true, pRight, pBackground);
548 if (mbHasCallout && pStyle->mpBottomCallout->GetNormalBitmap().is())
550 const sal_Int32 nCalloutWidth (pStyle->mpBottomCallout->mnWidth);
551 sal_Int32 nCalloutX (maCalloutAnchor.X - pStyle->mpBottomCallout->mnXHotSpot
552 - (aCenterBox.X - aOuterBox.X));
553 if (nCalloutX < pBottomLeft->mnXOffset + aCenterBox.X)
554 nCalloutX = pBottomLeft->mnXOffset + aCenterBox.X;
555 if (nCalloutX > pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width)
556 nCalloutX = pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width;
557 // Paint bottom callout.
558 PaintBitmap(aCenterBox, rUpdateBox, 0,+1, nCalloutX,0, false, pStyle->mpBottomCallout, pBackground);
559 // Paint regular bottom bitmap left and right.
560 PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
561 pBottomLeft->mnXOffset, nCalloutX-aCenterBox.Width, true, pBottom, pBackground);
562 PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
563 nCalloutX+nCalloutWidth, pBottomRight->mnXOffset, true, pBottom, pBackground);
565 else
567 // Stretch the bottom bitmap over the full width.
568 PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
569 pBottomLeft->mnXOffset, pBottomRight->mnXOffset, true, pBottom, pBackground);
572 // Paint the corners.
573 PaintBitmap(aCenterBox, rUpdateBox, -1,-1, 0,0, false, pTopLeft, pBackground);
574 PaintBitmap(aCenterBox, rUpdateBox, +1,-1, 0,0, false, pTopRight, pBackground);
575 PaintBitmap(aCenterBox, rUpdateBox, -1,+1, 0,0, false, pBottomLeft, pBackground);
576 PaintBitmap(aCenterBox, rUpdateBox, +1,+1, 0,0, false, pBottomRight, pBackground);
578 // Paint the title.
579 PaintTitle(rsTitle, pStyle, rUpdateBox, aOuterBox, aInnerBox, false);
581 // In a double buffering environment request to make the changes visible.
582 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
583 if (xSpriteCanvas.is())
584 xSpriteCanvas->updateScreen(sal_False);
590 void PresenterPaneBorderPainter::Renderer::PaintTitle (
591 const OUString& rsTitle,
592 const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
593 const awt::Rectangle& rUpdateBox,
594 const awt::Rectangle& rOuterBox,
595 const awt::Rectangle& rInnerBox,
596 bool bPaintBackground)
598 if ( ! mxCanvas.is())
599 return;
601 if (rsTitle.getLength() == 0)
602 return;
604 Reference<rendering::XCanvasFont> xFont (rpStyle->GetFont(mxCanvas));
605 if ( ! xFont.is())
606 return;
608 rendering::StringContext aContext (
609 rsTitle,
611 rsTitle.getLength());
612 Reference<rendering::XTextLayout> xLayout (xFont->createTextLayout(
613 aContext,
614 rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
615 0));
616 if ( ! xLayout.is())
617 return;
619 geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
620 const double nTextHeight = aBox.Y2 - aBox.Y1;
621 const double nTextWidth = aBox.X2 - aBox.X1;
622 double nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
623 const sal_Int32 nTitleBarHeight = rInnerBox.Y - rOuterBox.Y - 1;
624 double nY = rOuterBox.Y + (nTitleBarHeight - nTextHeight) / 2 - aBox.Y1;
625 if (nY >= rInnerBox.Y)
626 nY = rInnerBox.Y - 1;
627 switch (rpStyle->meFontAnchor)
629 default:
630 case RendererPaneStyle::AnchorLeft:
631 nX = rInnerBox.X;
632 break;
633 case RendererPaneStyle::AnchorRight:
634 nX = rInnerBox.X + rInnerBox.Width - nTextWidth;
635 break;
636 case RendererPaneStyle::AnchorCenter:
637 nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
638 break;
640 nX += rpStyle->mnFontXOffset;
641 nY += rpStyle->mnFontYOffset;
643 if (rUpdateBox.X >= nX+nTextWidth
644 || rUpdateBox.Y >= nY+nTextHeight
645 || rUpdateBox.X+rUpdateBox.Width <= nX
646 || rUpdateBox.Y+rUpdateBox.Height <= nY)
648 return;
651 rendering::RenderState aRenderState(
652 geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
653 NULL,
654 Sequence<double>(4),
655 rendering::CompositeOperation::SOURCE);
657 if (bPaintBackground)
659 PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
660 Sequence<Sequence<geometry::RealPoint2D> > aPolygons(1);
661 aPolygons[0] = Sequence<geometry::RealPoint2D>(4);
662 aPolygons[0][0] = geometry::RealPoint2D(0, -nTextHeight);
663 aPolygons[0][1] = geometry::RealPoint2D(0, 0);
664 aPolygons[0][2] = geometry::RealPoint2D(nTextWidth, 0);
665 aPolygons[0][3] = geometry::RealPoint2D(nTextWidth, -nTextHeight);
666 Reference<rendering::XPolyPolygon2D> xPolygon (
667 mxCanvas->getDevice()->createCompatibleLinePolyPolygon(aPolygons), UNO_QUERY);
668 if (xPolygon.is())
669 xPolygon->setClosed(0, sal_True);
670 mxCanvas->fillPolyPolygon(
671 xPolygon,
672 maViewState,
673 aRenderState);
675 else
677 PresenterCanvasHelper::SetDeviceColor(
678 aRenderState,
679 rpStyle->mpFont->mnColor);
681 mxCanvas->drawText(
682 aContext,
683 xFont,
684 maViewState,
685 aRenderState,
686 rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
692 ::boost::shared_ptr<RendererPaneStyle>
693 PresenterPaneBorderPainter::Renderer::GetRendererPaneStyle (const OUString& rsResourceURL)
695 OSL_ASSERT(mpTheme.get()!=NULL);
697 RendererPaneStyleContainer::const_iterator iStyle (maRendererPaneStyles.find(rsResourceURL));
698 if (iStyle == maRendererPaneStyles.end())
700 OUString sPaneStyleName (OUString::createFromAscii("DefaultRendererPaneStyle"));
702 // Get pane layout name for resource URL.
703 const OUString sStyleName (mpTheme->GetStyleName(rsResourceURL));
704 if (sStyleName.getLength() > 0)
705 sPaneStyleName = sStyleName;
707 // Create a new pane style object and initialize it with bitmaps.
708 ::boost::shared_ptr<RendererPaneStyle> pStyle (
709 new RendererPaneStyle(mpTheme,sPaneStyleName));
710 iStyle = maRendererPaneStyles.insert(
711 RendererPaneStyleContainer::value_type(rsResourceURL, pStyle)).first;
713 if (iStyle != maRendererPaneStyles.end())
714 return iStyle->second;
715 else
716 return ::boost::shared_ptr<RendererPaneStyle>();
722 void PresenterPaneBorderPainter::Renderer::SetCalloutAnchor (
723 const awt::Point& rCalloutAnchor)
725 mbHasCallout = true;
726 maCalloutAnchor = rCalloutAnchor;
732 void PresenterPaneBorderPainter::Renderer::PaintBitmap(
733 const awt::Rectangle& rBox,
734 const awt::Rectangle& rUpdateBox,
735 const sal_Int32 nXPosition,
736 const sal_Int32 nYPosition,
737 const sal_Int32 nStartOffset,
738 const sal_Int32 nEndOffset,
739 const bool bExpand,
740 const SharedBitmapDescriptor& rpBitmap,
741 const SharedBitmapDescriptor& rpBackgroundBitmap)
743 (void)rpBackgroundBitmap;
745 bool bUseCanvas (mxCanvas.is());
746 if ( ! bUseCanvas)
747 return;
749 if (rpBitmap->mnWidth<=0 || rpBitmap->mnHeight<=0)
750 return;
752 Reference<rendering::XBitmap> xBitmap (rpBitmap->GetNormalBitmap(), UNO_QUERY);
753 if ( ! xBitmap.is())
754 return;
756 // Calculate position, and for side bitmaps, the size.
757 sal_Int32 nX = 0;
758 sal_Int32 nY = 0;
759 sal_Int32 nW = rpBitmap->mnWidth;
760 sal_Int32 nH = rpBitmap->mnHeight;
761 if (nXPosition < 0)
763 nX = rBox.X - rpBitmap->mnWidth + rpBitmap->mnXOffset;
765 else if (nXPosition > 0)
767 nX = rBox.X + rBox.Width + rpBitmap->mnXOffset;
769 else
771 nX = rBox.X + nStartOffset;
772 if (bExpand)
773 nW = rBox.Width - nStartOffset + nEndOffset;
776 if (nYPosition < 0)
778 nY = rBox.Y - rpBitmap->mnHeight + rpBitmap->mnYOffset;
780 else if (nYPosition > 0)
782 nY = rBox.Y + rBox.Height + rpBitmap->mnYOffset;
784 else
786 nY = rBox.Y + nStartOffset;
787 if (bExpand)
788 nH = rBox.Height - nStartOffset + nEndOffset;
791 // Do not paint when bitmap area does not intersect with update box.
792 if (nX >= rUpdateBox.X + rUpdateBox.Width
793 || nX+nW <= rUpdateBox.X
794 || nY >= rUpdateBox.Y + rUpdateBox.Height
795 || nY+nH <= rUpdateBox.Y)
797 return;
801 Reference<rendering::XBitmap> xMaskedBitmap (
802 PresenterBitmapHelper::FillMaskedWithColor (
803 mxCanvas,
804 Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
805 rBitmap.mxMaskBitmap,
806 0x00ff0000,
807 rBackgroundBitmap.maReplacementColor));
808 if (xMaskedBitmap.is())
809 xBitmap = xMaskedBitmap;
810 else if (rBitmap.mxMaskBitmap.is() && mxPresenterHelper.is())
812 const static sal_Int32 nOutsideMaskColor (0x00ff0000);
813 Reference<rendering::XIntegerBitmap> xMask (
814 mxPresenterHelper->createMask(
815 mxCanvas,
816 rBitmap.mxMaskBitmap,
817 nOutsideMaskColor,
818 false));
819 xBitmap = mxPresenterHelper->applyBitmapMaskWithColor(
820 mxCanvas,
821 Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
822 xMask,
823 rBackgroundBitmap.maReplacementColor);
826 rendering::RenderState aRenderState (
827 geometry::AffineMatrix2D(
828 double(nW)/rpBitmap->mnWidth, 0, nX,
829 0, double(nH)/rpBitmap->mnHeight, nY),
830 NULL,
831 Sequence<double>(4),
832 rendering::CompositeOperation::OVER);
834 if (xBitmap.is())
835 mxCanvas->drawBitmap(
836 xBitmap,
837 maViewState,
838 aRenderState);
844 void PresenterPaneBorderPainter::Renderer::SetupClipping (
845 const awt::Rectangle& rUpdateBox,
846 const awt::Rectangle& rOuterBox,
847 const OUString& rsPaneStyleName)
849 mxViewStateClip = NULL;
850 maViewState.Clip = NULL;
852 if ( ! mxCanvas.is())
853 return;
855 ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneStyleName));
856 if (pStyle.get() == NULL)
858 mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
859 rUpdateBox,
860 mxCanvas->getDevice());
862 else
864 awt::Rectangle aInnerBox (
865 pStyle->RemoveBorder(rOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
866 ::std::vector<awt::Rectangle> aRectangles;
867 aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, rOuterBox));
868 aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, aInnerBox));
869 mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
870 aRectangles,
871 mxCanvas->getDevice());
872 if (mxViewStateClip.is())
873 mxViewStateClip->setFillRule(rendering::FillRule_EVEN_ODD);
875 maViewState.Clip = mxViewStateClip;
880 namespace {
882 //===== BorderSize ============================================================
884 BorderSize::BorderSize (void)
885 : mnLeft(0),
886 mnTop(0),
887 mnRight(0),
888 mnBottom(0)
895 BorderSize::BorderSize (const BorderSize& rBorderSize)
896 : mnLeft(rBorderSize.mnLeft),
897 mnTop(rBorderSize.mnTop),
898 mnRight(rBorderSize.mnRight),
899 mnBottom(rBorderSize.mnBottom)
906 BorderSize& BorderSize::operator= (const BorderSize& rBorderSize)
908 if (&rBorderSize != this)
910 mnLeft = rBorderSize.mnLeft;
911 mnTop = rBorderSize.mnTop;
912 mnRight = rBorderSize.mnRight;
913 mnBottom = rBorderSize.mnBottom;
915 return *this;
921 //===== RendererPaneStyle ============================================================
923 RendererPaneStyle::RendererPaneStyle (
924 const ::boost::shared_ptr<PresenterTheme>& rpTheme,
925 const OUString& rsStyleName)
926 : mpTopLeft(),
927 mpTop(),
928 mpTopRight(),
929 mpLeft(),
930 mpRight(),
931 mpBottomLeft(),
932 mpBottom(),
933 mpBottomRight(),
934 mpBottomCallout(),
935 mpBackground(),
936 mpEmpty(new PresenterBitmapDescriptor()),
937 mpFont(),
938 mnFontXOffset(0),
939 mnFontYOffset(0),
940 meFontAnchor(AnchorCenter),
941 maInnerBorderSize(),
942 maOuterBorderSize(),
943 maTotalBorderSize()
945 if (rpTheme.get() != NULL)
947 mpTopLeft = GetBitmap(rpTheme, rsStyleName, A2S("TopLeft"));
948 mpTop = GetBitmap(rpTheme, rsStyleName, A2S("Top"));
949 mpTopRight = GetBitmap(rpTheme, rsStyleName, A2S("TopRight"));
950 mpLeft = GetBitmap(rpTheme, rsStyleName, A2S("Left"));
951 mpRight = GetBitmap(rpTheme, rsStyleName, A2S("Right"));
952 mpBottomLeft = GetBitmap(rpTheme, rsStyleName, A2S("BottomLeft"));
953 mpBottom = GetBitmap(rpTheme, rsStyleName, A2S("Bottom"));
954 mpBottomRight = GetBitmap(rpTheme, rsStyleName, A2S("BottomRight"));
955 mpBottomCallout = GetBitmap(rpTheme, rsStyleName, A2S("BottomCallout"));
956 mpBackground = GetBitmap(rpTheme, OUString(), A2S("Background"));
958 // Get font description.
959 mpFont = rpTheme->GetFont(rsStyleName);
961 OUString sAnchor (OUString::createFromAscii("Left"));
962 if (mpFont.get() != NULL)
964 sAnchor = mpFont->msAnchor;
965 mnFontXOffset = mpFont->mnXOffset;
966 mnFontYOffset = mpFont->mnYOffset;
969 if (sAnchor == OUString::createFromAscii("Left"))
970 meFontAnchor = AnchorLeft;
971 else if (sAnchor == OUString::createFromAscii("Right"))
972 meFontAnchor = AnchorRight;
973 else if (sAnchor == OUString::createFromAscii("Center"))
974 meFontAnchor = AnchorCenter;
975 else
976 meFontAnchor = AnchorCenter;
978 // Get border sizes.
981 ::std::vector<sal_Int32> aInnerBorder (rpTheme->GetBorderSize(rsStyleName, false));
982 OSL_ASSERT(aInnerBorder.size()==4);
983 maInnerBorderSize.mnLeft = aInnerBorder[0];
984 maInnerBorderSize.mnTop = aInnerBorder[1];
985 maInnerBorderSize.mnRight = aInnerBorder[2];
986 maInnerBorderSize.mnBottom = aInnerBorder[3];
988 ::std::vector<sal_Int32> aOuterBorder (rpTheme->GetBorderSize(rsStyleName, true));
989 OSL_ASSERT(aOuterBorder.size()==4);
990 maOuterBorderSize.mnLeft = aOuterBorder[0];
991 maOuterBorderSize.mnTop = aOuterBorder[1];
992 maOuterBorderSize.mnRight = aOuterBorder[2];
993 maOuterBorderSize.mnBottom = aOuterBorder[3];
995 catch(beans::UnknownPropertyException&)
997 OSL_ASSERT(false);
1000 UpdateBorderSizes();
1008 awt::Rectangle RendererPaneStyle::AddBorder (
1009 const awt::Rectangle& rBox,
1010 const drawing::framework::BorderType eBorderType) const
1012 const BorderSize* pBorderSize = NULL;
1013 switch (eBorderType)
1015 case drawing::framework::BorderType_INNER_BORDER:
1016 pBorderSize = &maInnerBorderSize;
1017 break;
1018 case drawing::framework::BorderType_OUTER_BORDER:
1019 pBorderSize = &maOuterBorderSize;
1020 break;
1021 case drawing::framework::BorderType_TOTAL_BORDER:
1022 pBorderSize = &maTotalBorderSize;
1023 break;
1024 default:
1025 return rBox;
1027 return awt::Rectangle (
1028 rBox.X - pBorderSize->mnLeft,
1029 rBox.Y - pBorderSize->mnTop,
1030 rBox.Width + pBorderSize->mnLeft + pBorderSize->mnRight,
1031 rBox.Height + pBorderSize->mnTop + pBorderSize->mnBottom);
1037 awt::Rectangle RendererPaneStyle::RemoveBorder (
1038 const awt::Rectangle& rBox,
1039 const css::drawing::framework::BorderType eBorderType) const
1041 const BorderSize* pBorderSize = NULL;
1042 switch (eBorderType)
1044 case drawing::framework::BorderType_INNER_BORDER:
1045 pBorderSize = &maInnerBorderSize;
1046 break;
1047 case drawing::framework::BorderType_OUTER_BORDER:
1048 pBorderSize = &maOuterBorderSize;
1049 break;
1050 case drawing::framework::BorderType_TOTAL_BORDER:
1051 pBorderSize = &maTotalBorderSize;
1052 break;
1053 default:
1054 return rBox;
1056 return awt::Rectangle (
1057 rBox.X + pBorderSize->mnLeft,
1058 rBox.Y + pBorderSize->mnTop,
1059 rBox.Width - pBorderSize->mnLeft - pBorderSize->mnRight,
1060 rBox.Height - pBorderSize->mnTop - pBorderSize->mnBottom);
1066 const Reference<rendering::XCanvasFont> RendererPaneStyle::GetFont (
1067 const Reference<rendering::XCanvas>& rxCanvas) const
1069 if (mpFont.get() != NULL)
1070 mpFont->PrepareFont(rxCanvas);
1071 return mpFont->mxFont;
1077 void RendererPaneStyle::UpdateBorderSizes (void)
1079 maTotalBorderSize.mnLeft = maInnerBorderSize.mnLeft + maOuterBorderSize.mnLeft;
1080 maTotalBorderSize.mnTop = maInnerBorderSize.mnTop + maOuterBorderSize.mnTop;
1081 maTotalBorderSize.mnRight = maInnerBorderSize.mnRight + maOuterBorderSize.mnRight;
1082 maTotalBorderSize.mnBottom = maInnerBorderSize.mnBottom + maOuterBorderSize.mnBottom;
1088 SharedBitmapDescriptor RendererPaneStyle::GetBitmap(
1089 const ::boost::shared_ptr<PresenterTheme>& rpTheme,
1090 const OUString& rsStyleName,
1091 const OUString& rsBitmapName)
1093 SharedBitmapDescriptor pDescriptor (rpTheme->GetBitmap(rsStyleName, rsBitmapName));
1094 if (pDescriptor.get() != NULL)
1095 return pDescriptor;
1096 else
1097 return mpEmpty;
1102 } // end of anonymous namespace
1105 } } // end of namespace ::sd::presenter