summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drawinglayer/source/attribute/sdrfillattribute.cxx16
-rw-r--r--include/drawinglayer/attribute/sdrfillattribute.hxx5
-rw-r--r--include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx1
-rw-r--r--svx/source/sdr/primitive2d/sdrattributecreator.cxx14
-rw-r--r--svx/source/sdr/primitive2d/sdrdecompositiontools.cxx247
5 files changed, 280 insertions, 3 deletions
diff --git a/drawinglayer/source/attribute/sdrfillattribute.cxx b/drawinglayer/source/attribute/sdrfillattribute.cxx
index b582ee0a11d0..131061099715 100644
--- a/drawinglayer/source/attribute/sdrfillattribute.cxx
+++ b/drawinglayer/source/attribute/sdrfillattribute.cxx
@@ -81,6 +81,11 @@ namespace drawinglayer::attribute
static SdrFillAttribute::ImplType SINGLETON;
return SINGLETON;
}
+ SdrFillAttribute::ImplType& slideBackgroundFillGlobalDefault()
+ {
+ static SdrFillAttribute::ImplType SINGLETON2;
+ return SINGLETON2;
+ }
}
SdrFillAttribute::SdrFillAttribute(
@@ -94,8 +99,10 @@ namespace drawinglayer::attribute
{
}
- SdrFillAttribute::SdrFillAttribute()
- : mpSdrFillAttribute(theGlobalDefault())
+ SdrFillAttribute::SdrFillAttribute(bool bSlideBackgroundFill)
+ : mpSdrFillAttribute(bSlideBackgroundFill
+ ? slideBackgroundFillGlobalDefault()
+ : theGlobalDefault())
{
}
@@ -110,6 +117,11 @@ namespace drawinglayer::attribute
return mpSdrFillAttribute.same_object(theGlobalDefault());
}
+ bool SdrFillAttribute::isSlideBackgroundFill() const
+ {
+ return mpSdrFillAttribute.same_object(slideBackgroundFillGlobalDefault());
+ }
+
SdrFillAttribute& SdrFillAttribute::operator=(const SdrFillAttribute&) = default;
SdrFillAttribute& SdrFillAttribute::operator=(SdrFillAttribute&&) = default;
diff --git a/include/drawinglayer/attribute/sdrfillattribute.hxx b/include/drawinglayer/attribute/sdrfillattribute.hxx
index 93fc7ca8541c..6ba140065d4c 100644
--- a/include/drawinglayer/attribute/sdrfillattribute.hxx
+++ b/include/drawinglayer/attribute/sdrfillattribute.hxx
@@ -56,7 +56,7 @@ namespace drawinglayer::attribute
const FillGradientAttribute& rGradient,
const FillHatchAttribute& rHatch,
const SdrFillGraphicAttribute& rFillGraphic);
- SdrFillAttribute();
+ SdrFillAttribute(bool bSlideBackgroundFill = false);
SdrFillAttribute(const SdrFillAttribute&);
SdrFillAttribute(SdrFillAttribute&&);
SdrFillAttribute& operator=(const SdrFillAttribute&);
@@ -66,6 +66,9 @@ namespace drawinglayer::attribute
// checks if the incarnation is default constructed
bool isDefault() const;
+ // checks if the incarnation is slideBackgroundFill
+ bool isSlideBackgroundFill() const;
+
// compare operator
bool operator==(const SdrFillAttribute& rCandidate) const;
diff --git a/include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx b/include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx
index 0af20f04d710..917d22f149da 100644
--- a/include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx
+++ b/include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx
@@ -49,6 +49,7 @@
#define PRIMITIVE2D_ID_SDRCHAINEDTEXTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 23)
#define PRIMITIVE2D_ID_SDRFRAMEBORDERTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 24)
#define PRIMITIVE2D_ID_OVERLAYDIAGRAMPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 25)
+#define PRIMITIVE2D_ID_SLIDEBACKGROUNDFILLPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 26)
#endif // INCLUDED_SVX_SDR_PRIMITIVE2D_SVX_PRIMITIVETYPES2D_HXX
diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
index 65245509440f..bafa96f95cd8 100644
--- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx
+++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
@@ -40,6 +40,7 @@
#include <svx/xlnedcit.hxx>
#include <svx/xdash.hxx>
#include <svx/xlndsit.hxx>
+#include <svx/xfilluseslidebackgrounditem.hxx>
#include <svx/xfltrit.hxx>
#include <svx/xflftrit.hxx>
#include <svx/xflclit.hxx>
@@ -418,6 +419,19 @@ namespace drawinglayer::primitive2d
nTransparence = 100;
}
+ if(drawing::FillStyle_NONE == eStyle)
+ {
+ XFillUseSlideBackgroundItem aBckItem(rSet.Get(XATTR_FILLUSESLIDEBACKGROUND));
+ const bool bSlideBackgroundFill(aBckItem.GetValue());
+
+ if(bSlideBackgroundFill)
+ {
+ // we have SlideBackgroundFill mode, create a
+ // SdrFillAttribute accordingly
+ return attribute::SdrFillAttribute(true);
+ }
+ }
+
if(drawing::FillStyle_NONE != eStyle)
{
if(100 != nTransparence)
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index 18f1a0918fed..6026a655cfa0 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -51,6 +51,15 @@
#include <drawinglayer/attribute/sdrglowattribute.hxx>
#include <osl/diagnose.h>
+// for SlideBackgroundFillPrimitive2D
+#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
+#include <svx/unoapi.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
+#include <svx/sdr/contact/viewobjectcontact.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
using namespace com::sun::star;
@@ -122,8 +131,238 @@ basegfx::B2DRange getTextAnchorRange(const attribute::SdrTextAttribute& rText,
}
return aAnchorRange;
}
+
+sdr::contact::ViewContact* getMasterPageViewContact(
+ const geometry::ViewInformation2D& rViewInformation,
+ basegfx::B2DVector& rPageSize)
+{
+ // get SdrPage
+ const SdrPage* pVisualizedPage(GetSdrPageFromXDrawPage(rViewInformation.getVisualizedPage()));
+ if(nullptr == pVisualizedPage)
+ return nullptr;
+
+ // do not use in MasterPage mode, so initial SdrPage shall *not* be a
+ // MasterPage
+ if(pVisualizedPage->IsMasterPage())
+ return nullptr;
+
+ // we need that SdrPage to have a MasterPage
+ if(!pVisualizedPage->TRG_HasMasterPage())
+ return nullptr;
+
+ // copy needed values for processing
+ rPageSize.setX(pVisualizedPage->GetWidth());
+ rPageSize.setY(pVisualizedPage->GetHeight());
+
+ // return it's ViewContact
+ return &pVisualizedPage->TRG_GetMasterPageDescriptorViewContact();
+}
+
+// provide a Primitive2D for the SlideBackgroundFill-mode. It is capable
+// of expressing that state of fill and it's decomposition implements all
+// needed preparation of the geometry in an isolated and controllable
+// space and way.
+// It is currently simple buffered (due to being derived from
+// BufferedDecompositionPrimitive2D) and detects if MasterPage changes
+class SlideBackgroundFillPrimitive2D final : public BufferedDecompositionPrimitive2D
+{
+private:
+ /// the basegfx::B2DPolyPolygon geometry
+ basegfx::B2DPolyPolygon maPolyPolygon;
+
+ /// the polygon fill color - to allow simple fallback if needed
+ basegfx::BColor maBColor;
+
+ /// the last VC the geometry was created for
+ sdr::contact::ViewContact* mpLastVC;
+
+protected:
+ // create decomposition data
+ virtual void create2DDecomposition(
+ Primitive2DContainer& rContainer,
+ const geometry::ViewInformation2D& rViewInformation) const override;
+
+public:
+ /// constructor
+ SlideBackgroundFillPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const basegfx::BColor& rBColor);
+
+ /// check existing decomposition data, call parent
+ virtual void get2DDecomposition(
+ Primitive2DDecompositionVisitor& rVisitor,
+ const geometry::ViewInformation2D& rViewInformation) const override;
+
+ /// data read access
+ const basegfx::B2DPolyPolygon& getB2DPolyPolygon() const { return maPolyPolygon; }
+ const basegfx::BColor& getBColor() const { return maBColor; }
+
+ /// compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
+
+ /// get range
+ virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override;
+
+ /// provide unique ID
+ virtual sal_uInt32 getPrimitive2DID() const override;
};
+SlideBackgroundFillPrimitive2D::SlideBackgroundFillPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const basegfx::BColor& rBColor)
+: BufferedDecompositionPrimitive2D()
+, maPolyPolygon(rPolyPolygon)
+, maBColor(rBColor)
+, mpLastVC(nullptr)
+{
+}
+
+void SlideBackgroundFillPrimitive2D::create2DDecomposition(
+ Primitive2DContainer& rContainer,
+ const geometry::ViewInformation2D& rViewInformation) const
+{
+ basegfx::B2DVector aPageSize;
+ sdr::contact::ViewContact* pViewContact(getMasterPageViewContact(rViewInformation, aPageSize));
+
+ // Check that we have a referenced SdrPage that is no MasterPage itself and has a MasterPage,
+ // we got it's ViewContact in pViewContact
+ if(nullptr != pViewContact)
+ {
+ // Get PolygonRange of own local geometry
+ const basegfx::B2DRange aPolygonRange(getB2DPolyPolygon().getB2DRange());
+
+ // if local geometry is empty, nothing will be shown, we are done
+ if(aPolygonRange.isEmpty())
+ return;
+
+ // Get PageRange
+ const basegfx::B2DRange aPageRange(0.0, 0.0, aPageSize.getX(), aPageSize.getY());
+
+ // if local geometry does not overlap with PageRange, nothing will be shown, we are done
+ if(!aPageRange.overlaps(aPolygonRange))
+ return;
+
+ // Get the geometry
+
+ // Add the MasterPage BG fill (if used, e.g. Picture/gradient, ...)
+ pViewContact->getViewIndependentPrimitive2DContainer(rContainer);
+
+ // To create the MasterPage's ObjectHierarchy we need an ObjectContact (AKA View-side of things).
+ // We do not have one, but can use a temporary one anytime for temporary work. That whole VC/VOC/OC
+ // is designed to work with on-demand temporary objects if needed
+ sdr::contact::ObjectContact aObjectContact;
+
+ // get the VOC from it (gets created)
+ sdr::contact::ViewObjectContact& rViewObjectContact(pViewContact->GetViewObjectContact(aObjectContact));
+ sdr::contact::DisplayInfo aDisplayInfo;
+
+ // we need this DisplayInfo-flag here - exceptionally - to get the same output as
+ // if the MasterPage is used as sub-content when creating geometry content for
+ // the non-MasterPage-view
+ aDisplayInfo.SetSubContentActive(true);
+
+ // get the full MasterPage ObjectHierarchy
+ rViewObjectContact.getPrimitive2DSequenceSubHierarchy(aDisplayInfo, rContainer);
+
+ if(!rContainer.empty())
+ {
+ // We got the geometry, but it may overlap the PageBounds of the
+ // Page/MasterPage, thus showing more beyond the PageBorders than
+ // the regular PageView does and is intended.
+ // This is independent from the geometry we collected in rContainer
+ // since the defining geometry is the getB2DPolyPolygon() one.
+ // We have already checked above that it's no empty and overlaps
+ // somehow.
+ // It also might be completely insinde the PageRange. If not, we
+ // additionally would need to mask the content against PageBounds,
+ // so using potentially two different MaskPrimitive2D's.
+ // Since in this case we have a PolyPolygon and a B2DRange it is cheaper
+ // to geometrically clip that PolyPolygon geometry and use it
+ basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
+
+ if(!aPageRange.isInside(aPolygonRange))
+ {
+ // we need to clip local geometry against PageBounds
+ aPolyPolygon = basegfx::utils::clipPolyPolygonOnRange(
+ aPolyPolygon,
+ aPageRange,
+ true /* bInside, use inside geometry */,
+ false /* bStroke, handle as filled PolyPolygon */);
+ }
+
+ // create MaskPrimitive2D to limit display to PolygonGeometry
+ const Primitive2DReference aMasked(
+ new MaskPrimitive2D(
+ aPolyPolygon,
+ std::move(rContainer)));
+
+ rContainer = Primitive2DContainer { aMasked };
+ return;
+ }
+ }
+
+ // fallback: create as if drawing::FillStyle_SOLID was used
+ rContainer.push_back(
+ new PolyPolygonColorPrimitive2D(
+ getB2DPolyPolygon(),
+ getBColor()));
+}
+
+void SlideBackgroundFillPrimitive2D::get2DDecomposition(
+ Primitive2DDecompositionVisitor& rVisitor,
+ const geometry::ViewInformation2D& rViewInformation) const
+{
+ basegfx::B2DVector aPageSize;
+ sdr::contact::ViewContact* pViewContact(getMasterPageViewContact(rViewInformation, aPageSize));
+
+ if(!getBuffered2DDecomposition().empty())
+ {
+ if(nullptr != pViewContact && pViewContact != mpLastVC)
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< SlideBackgroundFillPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DContainer());
+ }
+ }
+
+ if(getBuffered2DDecomposition().empty())
+ {
+ // remember last MasterPageViewContact
+ const_cast< SlideBackgroundFillPrimitive2D* >(this)->mpLastVC = pViewContact;
+ }
+
+ // use parent implementation
+ BufferedDecompositionPrimitive2D::get2DDecomposition(rVisitor, rViewInformation);
+}
+
+bool SlideBackgroundFillPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+{
+ if (BufferedDecompositionPrimitive2D::operator==(rPrimitive))
+ {
+ const SlideBackgroundFillPrimitive2D& rCompare
+ = static_cast<const SlideBackgroundFillPrimitive2D&>(rPrimitive);
+
+ return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
+ && getBColor() == rCompare.getBColor());
+ }
+
+ return false;
+}
+
+basegfx::B2DRange SlideBackgroundFillPrimitive2D::getB2DRange(
+ const geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+ // return range
+ return basegfx::utils::getRange(getB2DPolyPolygon());
+}
+
+// provide unique ID
+sal_uInt32 SlideBackgroundFillPrimitive2D::getPrimitive2DID() const
+{
+ return PRIMITIVE2D_ID_SLIDEBACKGROUNDFILLPRIMITIVE2D;
+}
+
+}; // end of anonymous namespace
+
class TransparencePrimitive2D;
Primitive2DReference createPolyPolygonFillPrimitive(
@@ -178,6 +417,14 @@ basegfx::B2DRange getTextAnchorRange(const attribute::SdrTextAttribute& rText,
rDefinitionRange,
rFill.getFillGraphic().createFillGraphicAttribute(rDefinitionRange));
}
+ else if(rFill.isSlideBackgroundFill())
+ {
+ // create needed Primitive2D representation for
+ // SlideBackgroundFill-mode
+ pNewFillPrimitive = new SlideBackgroundFillPrimitive2D(
+ rPolyPolygon,
+ rFill.getColor());
+ }
else
{
pNewFillPrimitive = new PolyPolygonColorPrimitive2D(