1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
43 using namespace ::com::sun::star
;
44 using namespace ::com::sun::star::uno
;
46 namespace sdext
{ namespace presenter
{
59 class RendererPaneStyle
63 const std::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 Reference
<rendering::XCanvasFont
> const & 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 mpEmpty
;
85 PresenterTheme::SharedFontDescriptor mpFont
;
86 sal_Int32 mnFontXOffset
;
87 sal_Int32 mnFontYOffset
;
88 enum class Anchor
{ Left
, Right
, Center
};
90 BorderSize maInnerBorderSize
;
91 BorderSize maOuterBorderSize
;
92 BorderSize maTotalBorderSize
;
93 enum Side
{ Left
, Top
, Right
, Bottom
};
95 void UpdateBorderSizes();
96 SharedBitmapDescriptor
GetBitmap(
97 const std::shared_ptr
<PresenterTheme
>& rpTheme
,
98 const OUString
& rsStyleName
,
99 const OUString
& rsBitmapName
);
103 class PresenterPaneBorderPainter::Renderer
107 const Reference
<XComponentContext
>& rxContext
,
108 const std::shared_ptr
<PresenterTheme
>& rpTheme
);
110 void SetCanvas (const Reference
<rendering::XCanvas
>& rxCanvas
);
112 const OUString
& rsTitle
,
113 const awt::Rectangle
& rBBox
,
114 const awt::Rectangle
& rUpdateBox
,
115 const OUString
& rsPaneURL
);
117 const OUString
& rsTitle
,
118 const std::shared_ptr
<RendererPaneStyle
>& rpStyle
,
119 const awt::Rectangle
& rUpdateBox
,
120 const awt::Rectangle
& rOuterBox
,
121 const awt::Rectangle
& rInnerBox
);
123 const awt::Rectangle
& rUpdateBox
,
124 const awt::Rectangle
& rOuterBox
,
125 const OUString
& rsPaneStyleName
);
126 std::shared_ptr
<RendererPaneStyle
> GetRendererPaneStyle (const OUString
& rsResourceURL
);
127 void SetCalloutAnchor (
128 const awt::Point
& rCalloutAnchor
);
131 std::shared_ptr
<PresenterTheme
> mpTheme
;
132 typedef ::std::map
<OUString
, std::shared_ptr
<RendererPaneStyle
> > RendererPaneStyleContainer
;
133 RendererPaneStyleContainer maRendererPaneStyles
;
134 Reference
<rendering::XCanvas
> mxCanvas
;
135 Reference
<drawing::XPresenterHelper
> mxPresenterHelper
;
136 css::rendering::ViewState maViewState
;
137 Reference
<rendering::XPolyPolygon2D
> mxViewStateClip
;
139 awt::Point maCalloutAnchor
;
142 const awt::Rectangle
& rBox
,
143 const awt::Rectangle
& rUpdateBox
,
144 const sal_Int32 nXPosition
,
145 const sal_Int32 nYPosition
,
146 const sal_Int32 nStartOffset
,
147 const sal_Int32 nEndOffset
,
149 const SharedBitmapDescriptor
& rpBitmap
);
152 // ===== PresenterPaneBorderPainter ===========================================
154 PresenterPaneBorderPainter::PresenterPaneBorderPainter (
155 const Reference
<XComponentContext
>& rxContext
)
156 : PresenterPaneBorderPainterInterfaceBase(m_aMutex
),
157 mxContext(rxContext
),
163 PresenterPaneBorderPainter::~PresenterPaneBorderPainter()
167 //----- XPaneBorderPainter ----------------------------------------------------
169 awt::Rectangle SAL_CALL
PresenterPaneBorderPainter::addBorder (
170 const OUString
& rsPaneBorderStyleName
,
171 const css::awt::Rectangle
& rRectangle
,
172 drawing::framework::BorderType eBorderType
)
178 return AddBorder(rsPaneBorderStyleName
, rRectangle
, eBorderType
);
181 awt::Rectangle SAL_CALL
PresenterPaneBorderPainter::removeBorder (
182 const OUString
& rsPaneBorderStyleName
,
183 const css::awt::Rectangle
& rRectangle
,
184 drawing::framework::BorderType eBorderType
)
190 return RemoveBorder(rsPaneBorderStyleName
, rRectangle
, eBorderType
);
193 void SAL_CALL
PresenterPaneBorderPainter::paintBorder (
194 const OUString
& rsPaneBorderStyleName
,
195 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
196 const css::awt::Rectangle
& rOuterBorderRectangle
,
197 const css::awt::Rectangle
& rRepaintArea
,
198 const OUString
& rsTitle
)
202 // Early reject paints completely outside the repaint area.
203 if (rRepaintArea
.X
>= rOuterBorderRectangle
.X
+rOuterBorderRectangle
.Width
204 || rRepaintArea
.Y
>= rOuterBorderRectangle
.Y
+rOuterBorderRectangle
.Height
205 || rRepaintArea
.X
+rRepaintArea
.Width
<= rOuterBorderRectangle
.X
206 || rRepaintArea
.Y
+rRepaintArea
.Height
<= rOuterBorderRectangle
.Y
)
210 ProvideTheme(rxCanvas
);
212 if (mpRenderer
.get() != nullptr)
214 mpRenderer
->SetCanvas(rxCanvas
);
215 mpRenderer
->SetupClipping(
217 rOuterBorderRectangle
,
218 rsPaneBorderStyleName
);
219 mpRenderer
->PaintBorder(
221 rOuterBorderRectangle
,
223 rsPaneBorderStyleName
);
227 void SAL_CALL
PresenterPaneBorderPainter::paintBorderWithCallout (
228 const OUString
& rsPaneBorderStyleName
,
229 const css::uno::Reference
<css::rendering::XCanvas
>& rxCanvas
,
230 const css::awt::Rectangle
& rOuterBorderRectangle
,
231 const css::awt::Rectangle
& rRepaintArea
,
232 const OUString
& rsTitle
,
233 const css::awt::Point
& rCalloutAnchor
)
237 // Early reject paints completely outside the repaint area.
238 if (rRepaintArea
.X
>= rOuterBorderRectangle
.X
+rOuterBorderRectangle
.Width
239 || rRepaintArea
.Y
>= rOuterBorderRectangle
.Y
+rOuterBorderRectangle
.Height
240 || rRepaintArea
.X
+rRepaintArea
.Width
<= rOuterBorderRectangle
.X
241 || rRepaintArea
.Y
+rRepaintArea
.Height
<= rOuterBorderRectangle
.Y
)
245 ProvideTheme(rxCanvas
);
247 if (mpRenderer
.get() != nullptr)
249 mpRenderer
->SetCanvas(rxCanvas
);
250 mpRenderer
->SetupClipping(
252 rOuterBorderRectangle
,
253 rsPaneBorderStyleName
);
254 mpRenderer
->SetCalloutAnchor(rCalloutAnchor
);
255 mpRenderer
->PaintBorder(
257 rOuterBorderRectangle
,
259 rsPaneBorderStyleName
);
263 awt::Point SAL_CALL
PresenterPaneBorderPainter::getCalloutOffset (
264 const OUString
& rsPaneBorderStyleName
)
268 if (mpRenderer
.get() != nullptr)
270 const std::shared_ptr
<RendererPaneStyle
> pRendererPaneStyle(
271 mpRenderer
->GetRendererPaneStyle(rsPaneBorderStyleName
));
272 if (pRendererPaneStyle
.get() != nullptr
273 && pRendererPaneStyle
->mpBottomCallout
.get() != nullptr)
277 pRendererPaneStyle
->mpBottomCallout
->mnHeight
278 - pRendererPaneStyle
->mpBottomCallout
->mnYHotSpot
);
282 return awt::Point(0,0);
286 bool PresenterPaneBorderPainter::ProvideTheme (const Reference
<rendering::XCanvas
>& rxCanvas
)
288 bool bModified (false);
290 if ( ! mxContext
.is())
293 if (mpTheme
.get() != nullptr)
295 // Check if the theme already has a canvas.
296 if ( ! mpTheme
->HasCanvas())
298 mpTheme
->ProvideCanvas(rxCanvas
);
304 mpTheme
.reset(new PresenterTheme(mxContext
, rxCanvas
));
308 if (mpTheme
.get() != nullptr && bModified
)
310 if (mpRenderer
.get() == nullptr)
311 mpRenderer
.reset(new Renderer(mxContext
, mpTheme
));
313 mpRenderer
->SetCanvas(rxCanvas
);
319 void PresenterPaneBorderPainter::ProvideTheme()
321 if (mpTheme
.get() == nullptr)
323 // Create a theme without bitmaps (no canvas => no bitmaps).
324 ProvideTheme(nullptr);
326 // When there already is a theme then without a canvas we can not
330 void PresenterPaneBorderPainter::SetTheme (const std::shared_ptr
<PresenterTheme
>& rpTheme
)
333 if (mpRenderer
.get() == nullptr)
334 mpRenderer
.reset(new Renderer(mxContext
, mpTheme
));
337 awt::Rectangle
PresenterPaneBorderPainter::AddBorder (
338 const OUString
& rsPaneURL
,
339 const awt::Rectangle
& rInnerBox
,
340 const css::drawing::framework::BorderType eBorderType
) const
342 if (mpRenderer
.get() != nullptr)
344 const std::shared_ptr
<RendererPaneStyle
> pRendererPaneStyle(mpRenderer
->GetRendererPaneStyle(rsPaneURL
));
345 if (pRendererPaneStyle
.get() != nullptr)
346 return pRendererPaneStyle
->AddBorder(rInnerBox
, eBorderType
);
351 awt::Rectangle
PresenterPaneBorderPainter::RemoveBorder (
352 const OUString
& rsPaneURL
,
353 const css::awt::Rectangle
& rOuterBox
,
354 const css::drawing::framework::BorderType eBorderType
) const
356 if (mpRenderer
.get() != nullptr)
358 const std::shared_ptr
<RendererPaneStyle
> pRendererPaneStyle(mpRenderer
->GetRendererPaneStyle(rsPaneURL
));
359 if (pRendererPaneStyle
.get() != nullptr)
360 return pRendererPaneStyle
->RemoveBorder(rOuterBox
, eBorderType
);
365 void PresenterPaneBorderPainter::ThrowIfDisposed() const
367 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
369 throw lang::DisposedException (
370 "PresenterPaneBorderPainter object has already been disposed",
371 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
375 //===== PresenterPaneBorderPainter::Renderer =====================================
377 PresenterPaneBorderPainter::Renderer::Renderer (
378 const Reference
<XComponentContext
>& rxContext
,
379 const std::shared_ptr
<PresenterTheme
>& rpTheme
)
381 maRendererPaneStyles(),
384 maViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), nullptr),
389 Reference
<lang::XMultiComponentFactory
> xFactory (rxContext
->getServiceManager());
392 mxPresenterHelper
.set(
393 xFactory
->createInstanceWithContext(
394 "com.sun.star.comp.Draw.PresenterHelper",
400 void PresenterPaneBorderPainter::Renderer::SetCanvas (const Reference
<rendering::XCanvas
>& rxCanvas
)
402 if (mxCanvas
!= rxCanvas
)
408 void PresenterPaneBorderPainter::Renderer::PaintBorder (
409 const OUString
& rsTitle
,
410 const awt::Rectangle
& rBBox
,
411 const awt::Rectangle
& rUpdateBox
,
412 const OUString
& rsPaneURL
)
414 if ( ! mxCanvas
.is())
417 // Create the outer and inner border of the, ahm, border.
418 std::shared_ptr
<RendererPaneStyle
> pStyle (GetRendererPaneStyle(rsPaneURL
));
419 if (pStyle
.get() == nullptr)
422 awt::Rectangle
aOuterBox (rBBox
);
423 awt::Rectangle
aCenterBox (
424 pStyle
->RemoveBorder(aOuterBox
, drawing::framework::BorderType_OUTER_BORDER
));
425 awt::Rectangle
aInnerBox (
426 pStyle
->RemoveBorder(aOuterBox
, drawing::framework::BorderType_TOTAL_BORDER
));
428 // Prepare references for all used bitmaps.
429 SharedBitmapDescriptor
pTop (pStyle
->mpTop
);
430 SharedBitmapDescriptor
pTopLeft (pStyle
->mpTopLeft
);
431 SharedBitmapDescriptor
pTopRight (pStyle
->mpTopRight
);
432 SharedBitmapDescriptor
pLeft (pStyle
->mpLeft
);
433 SharedBitmapDescriptor
pRight (pStyle
->mpRight
);
434 SharedBitmapDescriptor
pBottomLeft (pStyle
->mpBottomLeft
);
435 SharedBitmapDescriptor
pBottomRight (pStyle
->mpBottomRight
);
436 SharedBitmapDescriptor
pBottom (pStyle
->mpBottom
);
439 PaintBitmap(aCenterBox
, rUpdateBox
, 0,-1,
440 pTopLeft
->mnXOffset
, pTopRight
->mnXOffset
, true, pTop
);
441 PaintBitmap(aCenterBox
, rUpdateBox
, -1,0,
442 pTopLeft
->mnYOffset
, pBottomLeft
->mnYOffset
, true, pLeft
);
443 PaintBitmap(aCenterBox
, rUpdateBox
, +1,0,
444 pTopRight
->mnYOffset
, pBottomRight
->mnYOffset
, true, pRight
);
445 if (mbHasCallout
&& pStyle
->mpBottomCallout
->GetNormalBitmap().is())
447 const sal_Int32
nCalloutWidth (pStyle
->mpBottomCallout
->mnWidth
);
448 sal_Int32
nCalloutX (maCalloutAnchor
.X
- pStyle
->mpBottomCallout
->mnXHotSpot
449 - (aCenterBox
.X
- aOuterBox
.X
));
450 if (nCalloutX
< pBottomLeft
->mnXOffset
+ aCenterBox
.X
)
451 nCalloutX
= pBottomLeft
->mnXOffset
+ aCenterBox
.X
;
452 if (nCalloutX
> pBottomRight
->mnXOffset
+ aCenterBox
.X
+ aCenterBox
.Width
)
453 nCalloutX
= pBottomRight
->mnXOffset
+ aCenterBox
.X
+ aCenterBox
.Width
;
454 // Paint bottom callout.
455 PaintBitmap(aCenterBox
, rUpdateBox
, 0,+1, nCalloutX
,0, false, pStyle
->mpBottomCallout
);
456 // Paint regular bottom bitmap left and right.
457 PaintBitmap(aCenterBox
, rUpdateBox
, 0,+1,
458 pBottomLeft
->mnXOffset
, nCalloutX
-aCenterBox
.Width
, true, pBottom
);
459 PaintBitmap(aCenterBox
, rUpdateBox
, 0,+1,
460 nCalloutX
+nCalloutWidth
, pBottomRight
->mnXOffset
, true, pBottom
);
464 // Stretch the bottom bitmap over the full width.
465 PaintBitmap(aCenterBox
, rUpdateBox
, 0,+1,
466 pBottomLeft
->mnXOffset
, pBottomRight
->mnXOffset
, true, pBottom
);
469 // Paint the corners.
470 PaintBitmap(aCenterBox
, rUpdateBox
, -1,-1, 0,0, false, pTopLeft
);
471 PaintBitmap(aCenterBox
, rUpdateBox
, +1,-1, 0,0, false, pTopRight
);
472 PaintBitmap(aCenterBox
, rUpdateBox
, -1,+1, 0,0, false, pBottomLeft
);
473 PaintBitmap(aCenterBox
, rUpdateBox
, +1,+1, 0,0, false, pBottomRight
);
476 PaintTitle(rsTitle
, pStyle
, rUpdateBox
, aOuterBox
, aInnerBox
);
478 // In a double buffering environment request to make the changes visible.
479 Reference
<rendering::XSpriteCanvas
> xSpriteCanvas (mxCanvas
, UNO_QUERY
);
480 if (xSpriteCanvas
.is())
481 xSpriteCanvas
->updateScreen(false);
484 void PresenterPaneBorderPainter::Renderer::PaintTitle (
485 const OUString
& rsTitle
,
486 const std::shared_ptr
<RendererPaneStyle
>& rpStyle
,
487 const awt::Rectangle
& rUpdateBox
,
488 const awt::Rectangle
& rOuterBox
,
489 const awt::Rectangle
& rInnerBox
)
491 if ( ! mxCanvas
.is())
494 if (rsTitle
.isEmpty())
497 Reference
<rendering::XCanvasFont
> xFont (rpStyle
->GetFont(mxCanvas
));
501 rendering::StringContext
aContext (
504 rsTitle
.getLength());
505 Reference
<rendering::XTextLayout
> xLayout (xFont
->createTextLayout(
507 rendering::TextDirection::WEAK_LEFT_TO_RIGHT
,
512 /// this is responsible of the texts above the slide windows
513 geometry::RealRectangle2D
aBox (xLayout
->queryTextBounds());
514 const double nTextHeight
= aBox
.Y2
- aBox
.Y1
;
515 const double nTextWidth
= aBox
.X1
+ aBox
.X2
;
516 const sal_Int32 nTitleBarHeight
= rInnerBox
.Y
- rOuterBox
.Y
- 1;
517 double nY
= rOuterBox
.Y
+ (nTitleBarHeight
- nTextHeight
) / 2 - aBox
.Y1
;
518 if (nY
>= rInnerBox
.Y
)
519 nY
= rInnerBox
.Y
- 1;
521 switch (rpStyle
->meFontAnchor
)
523 case RendererPaneStyle::Anchor::Left
:
526 case RendererPaneStyle::Anchor::Right
:
527 nX
= rInnerBox
.X
+ rInnerBox
.Width
- nTextWidth
;
529 default: // RendererPaneStyle::Anchor::Center
530 nX
= rInnerBox
.X
+ (rInnerBox
.Width
- nTextWidth
)/2;
533 nX
+= rpStyle
->mnFontXOffset
;
534 nY
+= rpStyle
->mnFontYOffset
;
536 if (rUpdateBox
.X
>= nX
+nTextWidth
537 || rUpdateBox
.Y
>= nY
+nTextHeight
538 || rUpdateBox
.X
+rUpdateBox
.Width
<= nX
539 || rUpdateBox
.Y
+rUpdateBox
.Height
<= nY
)
544 rendering::RenderState
aRenderState(
545 geometry::AffineMatrix2D(1,0,nX
, 0,1,nY
),
548 rendering::CompositeOperation::SOURCE
);
550 PresenterCanvasHelper::SetDeviceColor(
552 rpStyle
->mpFont
->mnColor
);
554 mxCanvas
->drawTextLayout (
560 std::shared_ptr
<RendererPaneStyle
>
561 PresenterPaneBorderPainter::Renderer::GetRendererPaneStyle (const OUString
& rsResourceURL
)
563 OSL_ASSERT(mpTheme
.get()!=nullptr);
565 RendererPaneStyleContainer::const_iterator
iStyle (maRendererPaneStyles
.find(rsResourceURL
));
566 if (iStyle
== maRendererPaneStyles
.end())
568 OUString
sPaneStyleName ("DefaultRendererPaneStyle");
570 // Get pane layout name for resource URL.
571 const OUString
sStyleName (mpTheme
->GetStyleName(rsResourceURL
));
572 if (!sStyleName
.isEmpty())
573 sPaneStyleName
= sStyleName
;
575 // Create a new pane style object and initialize it with bitmaps.
576 std::shared_ptr
<RendererPaneStyle
> pStyle (
577 new RendererPaneStyle(mpTheme
,sPaneStyleName
));
578 iStyle
= maRendererPaneStyles
.emplace(rsResourceURL
, pStyle
).first
;
580 if (iStyle
!= maRendererPaneStyles
.end())
581 return iStyle
->second
;
583 return std::shared_ptr
<RendererPaneStyle
>();
586 void PresenterPaneBorderPainter::Renderer::SetCalloutAnchor (
587 const awt::Point
& rCalloutAnchor
)
590 maCalloutAnchor
= rCalloutAnchor
;
593 void PresenterPaneBorderPainter::Renderer::PaintBitmap(
594 const awt::Rectangle
& rBox
,
595 const awt::Rectangle
& rUpdateBox
,
596 const sal_Int32 nXPosition
,
597 const sal_Int32 nYPosition
,
598 const sal_Int32 nStartOffset
,
599 const sal_Int32 nEndOffset
,
601 const SharedBitmapDescriptor
& rpBitmap
)
603 bool bUseCanvas (mxCanvas
.is());
607 if (rpBitmap
->mnWidth
<=0 || rpBitmap
->mnHeight
<=0)
610 Reference
<rendering::XBitmap
> xBitmap (rpBitmap
->GetNormalBitmap(), UNO_QUERY
);
614 // Calculate position, and for side bitmaps, the size.
617 sal_Int32 nW
= rpBitmap
->mnWidth
;
618 sal_Int32 nH
= rpBitmap
->mnHeight
;
621 nX
= rBox
.X
- rpBitmap
->mnWidth
+ rpBitmap
->mnXOffset
;
623 else if (nXPosition
> 0)
625 nX
= rBox
.X
+ rBox
.Width
+ rpBitmap
->mnXOffset
;
629 nX
= rBox
.X
+ nStartOffset
;
631 nW
= rBox
.Width
- nStartOffset
+ nEndOffset
;
636 nY
= rBox
.Y
- rpBitmap
->mnHeight
+ rpBitmap
->mnYOffset
;
638 else if (nYPosition
> 0)
640 nY
= rBox
.Y
+ rBox
.Height
+ rpBitmap
->mnYOffset
;
644 nY
= rBox
.Y
+ nStartOffset
;
646 nH
= rBox
.Height
- nStartOffset
+ nEndOffset
;
649 // Do not paint when bitmap area does not intersect with update box.
650 if (nX
>= rUpdateBox
.X
+ rUpdateBox
.Width
651 || nX
+nW
<= rUpdateBox
.X
652 || nY
>= rUpdateBox
.Y
+ rUpdateBox
.Height
653 || nY
+nH
<= rUpdateBox
.Y
)
659 Reference<rendering::XBitmap> xMaskedBitmap (
660 PresenterBitmapHelper::FillMaskedWithColor (
662 Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
663 rBitmap.mxMaskBitmap,
665 rBackgroundBitmap.maReplacementColor));
666 if (xMaskedBitmap.is())
667 xBitmap = xMaskedBitmap;
668 else if (rBitmap.mxMaskBitmap.is() && mxPresenterHelper.is())
670 const static sal_Int32 nOutsideMaskColor (0x00ff0000);
671 Reference<rendering::XIntegerBitmap> xMask (
672 mxPresenterHelper->createMask(
674 rBitmap.mxMaskBitmap,
677 xBitmap = mxPresenterHelper->applyBitmapMaskWithColor(
679 Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
681 rBackgroundBitmap.maReplacementColor);
684 rendering::RenderState
aRenderState (
685 geometry::AffineMatrix2D(
686 double(nW
)/rpBitmap
->mnWidth
, 0, nX
,
687 0, double(nH
)/rpBitmap
->mnHeight
, nY
),
690 rendering::CompositeOperation::OVER
);
693 mxCanvas
->drawBitmap(
699 void PresenterPaneBorderPainter::Renderer::SetupClipping (
700 const awt::Rectangle
& rUpdateBox
,
701 const awt::Rectangle
& rOuterBox
,
702 const OUString
& rsPaneStyleName
)
704 mxViewStateClip
= nullptr;
705 maViewState
.Clip
= nullptr;
707 if ( ! mxCanvas
.is())
710 std::shared_ptr
<RendererPaneStyle
> pStyle (GetRendererPaneStyle(rsPaneStyleName
));
711 if (pStyle
.get() == nullptr)
713 mxViewStateClip
= PresenterGeometryHelper::CreatePolygon(
715 mxCanvas
->getDevice());
719 awt::Rectangle
aInnerBox (
720 pStyle
->RemoveBorder(rOuterBox
, drawing::framework::BorderType_TOTAL_BORDER
));
721 ::std::vector
<awt::Rectangle
> aRectangles
;
722 aRectangles
.push_back(PresenterGeometryHelper::Intersection(rUpdateBox
, rOuterBox
));
723 aRectangles
.push_back(PresenterGeometryHelper::Intersection(rUpdateBox
, aInnerBox
));
724 mxViewStateClip
= PresenterGeometryHelper::CreatePolygon(
726 mxCanvas
->getDevice());
727 if (mxViewStateClip
.is())
728 mxViewStateClip
->setFillRule(rendering::FillRule_EVEN_ODD
);
730 maViewState
.Clip
= mxViewStateClip
;
735 //===== BorderSize ============================================================
737 BorderSize::BorderSize()
745 //===== RendererPaneStyle ============================================================
747 RendererPaneStyle::RendererPaneStyle (
748 const std::shared_ptr
<PresenterTheme
>& rpTheme
,
749 const OUString
& rsStyleName
)
759 mpEmpty(new PresenterBitmapDescriptor()),
763 meFontAnchor(Anchor::Center
),
768 if (rpTheme
.get() != nullptr)
770 mpTopLeft
= GetBitmap(rpTheme
, rsStyleName
, "TopLeft");
771 mpTop
= GetBitmap(rpTheme
, rsStyleName
, "Top");
772 mpTopRight
= GetBitmap(rpTheme
, rsStyleName
, "TopRight");
773 mpLeft
= GetBitmap(rpTheme
, rsStyleName
,"Left");
774 mpRight
= GetBitmap(rpTheme
, rsStyleName
, "Right");
775 mpBottomLeft
= GetBitmap(rpTheme
, rsStyleName
, "BottomLeft");
776 mpBottom
= GetBitmap(rpTheme
, rsStyleName
, "Bottom");
777 mpBottomRight
= GetBitmap(rpTheme
, rsStyleName
, "BottomRight");
778 mpBottomCallout
= GetBitmap(rpTheme
, rsStyleName
, "BottomCallout");
780 // Get font description.
781 mpFont
= rpTheme
->GetFont(rsStyleName
);
783 OUString
sAnchor ("Left");
784 if (mpFont
.get() != nullptr)
786 sAnchor
= mpFont
->msAnchor
;
787 mnFontXOffset
= mpFont
->mnXOffset
;
788 mnFontYOffset
= mpFont
->mnYOffset
;
791 if ( sAnchor
== "Left" )
792 meFontAnchor
= Anchor::Left
;
793 else if ( sAnchor
== "Right" )
794 meFontAnchor
= Anchor::Right
;
796 meFontAnchor
= Anchor::Center
;
801 ::std::vector
<sal_Int32
> aInnerBorder (rpTheme
->GetBorderSize(rsStyleName
, false));
802 OSL_ASSERT(aInnerBorder
.size()==4);
803 maInnerBorderSize
.mnLeft
= aInnerBorder
[0];
804 maInnerBorderSize
.mnTop
= aInnerBorder
[1];
805 maInnerBorderSize
.mnRight
= aInnerBorder
[2];
806 maInnerBorderSize
.mnBottom
= aInnerBorder
[3];
808 ::std::vector
<sal_Int32
> aOuterBorder (rpTheme
->GetBorderSize(rsStyleName
, true));
809 OSL_ASSERT(aOuterBorder
.size()==4);
810 maOuterBorderSize
.mnLeft
= aOuterBorder
[0];
811 maOuterBorderSize
.mnTop
= aOuterBorder
[1];
812 maOuterBorderSize
.mnRight
= aOuterBorder
[2];
813 maOuterBorderSize
.mnBottom
= aOuterBorder
[3];
815 catch(beans::UnknownPropertyException
&)
824 awt::Rectangle
RendererPaneStyle::AddBorder (
825 const awt::Rectangle
& rBox
,
826 const drawing::framework::BorderType eBorderType
) const
828 const BorderSize
* pBorderSize
= nullptr;
831 case drawing::framework::BorderType_INNER_BORDER
:
832 pBorderSize
= &maInnerBorderSize
;
834 case drawing::framework::BorderType_OUTER_BORDER
:
835 pBorderSize
= &maOuterBorderSize
;
837 case drawing::framework::BorderType_TOTAL_BORDER
:
838 pBorderSize
= &maTotalBorderSize
;
843 return awt::Rectangle (
844 rBox
.X
- pBorderSize
->mnLeft
,
845 rBox
.Y
- pBorderSize
->mnTop
,
846 rBox
.Width
+ pBorderSize
->mnLeft
+ pBorderSize
->mnRight
,
847 rBox
.Height
+ pBorderSize
->mnTop
+ pBorderSize
->mnBottom
);
850 awt::Rectangle
RendererPaneStyle::RemoveBorder (
851 const awt::Rectangle
& rBox
,
852 const css::drawing::framework::BorderType eBorderType
) const
854 const BorderSize
* pBorderSize
= nullptr;
857 case drawing::framework::BorderType_INNER_BORDER
:
858 pBorderSize
= &maInnerBorderSize
;
860 case drawing::framework::BorderType_OUTER_BORDER
:
861 pBorderSize
= &maOuterBorderSize
;
863 case drawing::framework::BorderType_TOTAL_BORDER
:
864 pBorderSize
= &maTotalBorderSize
;
869 return awt::Rectangle (
870 rBox
.X
+ pBorderSize
->mnLeft
,
871 rBox
.Y
+ pBorderSize
->mnTop
,
872 rBox
.Width
- pBorderSize
->mnLeft
- pBorderSize
->mnRight
,
873 rBox
.Height
- pBorderSize
->mnTop
- pBorderSize
->mnBottom
);
876 Reference
<rendering::XCanvasFont
> const & RendererPaneStyle::GetFont (
877 const Reference
<rendering::XCanvas
>& rxCanvas
) const
879 if (mpFont
.get() != nullptr)
880 mpFont
->PrepareFont(rxCanvas
);
881 return mpFont
->mxFont
;
884 void RendererPaneStyle::UpdateBorderSizes()
886 maTotalBorderSize
.mnLeft
= maInnerBorderSize
.mnLeft
+ maOuterBorderSize
.mnLeft
;
887 maTotalBorderSize
.mnTop
= maInnerBorderSize
.mnTop
+ maOuterBorderSize
.mnTop
;
888 maTotalBorderSize
.mnRight
= maInnerBorderSize
.mnRight
+ maOuterBorderSize
.mnRight
;
889 maTotalBorderSize
.mnBottom
= maInnerBorderSize
.mnBottom
+ maOuterBorderSize
.mnBottom
;
892 SharedBitmapDescriptor
RendererPaneStyle::GetBitmap(
893 const std::shared_ptr
<PresenterTheme
>& rpTheme
,
894 const OUString
& rsStyleName
,
895 const OUString
& rsBitmapName
)
897 SharedBitmapDescriptor
pDescriptor (rpTheme
->GetBitmap(rsStyleName
, rsBitmapName
));
898 if (pDescriptor
.get() != nullptr)
904 } // end of anonymous namespace
906 } } // end of namespace ::sd::presenter
908 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */