libreoffice/bsc1183308.patch

1326 lines
58 KiB
Diff

From 80d99306107ce3335b1eafa14e880b814eddb98c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lunak@collabora.com>
Date: Fri, 7 Jan 2022 10:01:46 +0100
Subject: [PATCH] improve loading and rendering of many small shapes
(bsc#1183308)
Change-Id: I1e4d3b219e0d35be040c7a675b6c668e677acba8
---
comphelper/source/misc/anycompare.cxx | 207 ++++++++++++++++++
.../processor2d/vclhelperbufferdevice.cxx | 34 ++-
include/com/sun/star/uno/Sequence.hxx | 2 +
include/comphelper/anycompare.hxx | 22 ++
include/svx/sdasitm.hxx | 13 ++
.../svx/sdr/properties/defaultproperties.hxx | 3 +-
include/svx/sdr/properties/properties.hxx | 3 +-
include/svx/svdoashp.hxx | 4 +-
include/svx/svdobj.hxx | 4 +-
include/vcl/outdev.hxx | 3 +
solenv/clang-format/excludelist | 1 +
.../sdr/properties/attributeproperties.hxx | 3 +-
svx/inc/sdr/properties/captionproperties.hxx | 3 +-
svx/inc/sdr/properties/circleproperties.hxx | 3 +-
.../sdr/properties/connectorproperties.hxx | 3 +-
.../sdr/properties/customshapeproperties.hxx | 3 +-
svx/inc/sdr/properties/e3dsceneproperties.hxx | 3 +-
svx/inc/sdr/properties/emptyproperties.hxx | 3 +-
svx/inc/sdr/properties/graphicproperties.hxx | 3 +-
svx/inc/sdr/properties/groupproperties.hxx | 3 +-
svx/inc/sdr/properties/measureproperties.hxx | 3 +-
svx/inc/sdr/properties/pageproperties.hxx | 3 +-
.../sdr/properties/rectangleproperties.hxx | 3 +-
svx/inc/sdr/properties/textproperties.hxx | 3 +-
svx/source/items/customshapeitem.cxx | 129 +++++++----
.../sdr/properties/attributeproperties.cxx | 6 +-
.../sdr/properties/captionproperties.cxx | 5 +-
.../sdr/properties/circleproperties.cxx | 5 +-
.../sdr/properties/connectorproperties.cxx | 5 +-
.../sdr/properties/customshapeproperties.cxx | 5 +-
.../sdr/properties/defaultproperties.cxx | 3 +-
.../sdr/properties/e3dsceneproperties.cxx | 8 +-
svx/source/sdr/properties/emptyproperties.cxx | 3 +-
.../sdr/properties/graphicproperties.cxx | 7 +-
svx/source/sdr/properties/groupproperties.cxx | 8 +-
.../sdr/properties/measureproperties.cxx | 5 +-
svx/source/sdr/properties/oleproperties.cxx | 2 +-
svx/source/sdr/properties/pageproperties.cxx | 3 +-
svx/source/sdr/properties/properties.cxx | 2 +-
.../sdr/properties/rectangleproperties.cxx | 5 +-
svx/source/sdr/properties/textproperties.cxx | 5 +-
svx/source/svdraw/svdoashp.cxx | 4 +-
svx/source/svdraw/svdobj.cxx | 9 +-
svx/source/table/cell.cxx | 2 +-
vcl/headless/svpvd.cxx | 37 ++--
vcl/source/outdev/outdev.cxx | 9 +
46 files changed, 490 insertions(+), 112 deletions(-)
diff --git a/comphelper/source/misc/anycompare.cxx b/comphelper/source/misc/anycompare.cxx
index d802024e7502..2758062a1915 100644
--- a/comphelper/source/misc/anycompare.cxx
+++ b/comphelper/source/misc/anycompare.cxx
@@ -286,4 +286,211 @@ namespace comphelper
} // namespace comphelper
+#include <o3tl/hash_combine.hxx>
+#include <typelib/typedescription.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::TypeDescription;
+
+namespace comphelper {
+namespace {
+
+// This is like com::sun::star::uno::TypeDescription, but it uses TYPELIB_DANGER_GET
+// (which the code used originally, but it's easier to have a class to handle ownership).
+class TypeDescriptionRef
+{
+public:
+ TypeDescriptionRef(typelib_TypeDescriptionReference* typeDef)
+ {
+ TYPELIB_DANGER_GET(&typeDescr, typeDef);
+ }
+ ~TypeDescriptionRef() { TYPELIB_DANGER_RELEASE(typeDescr); }
+ typelib_TypeDescription* get() { return typeDescr; }
+ typelib_TypeDescription* operator->() { return typeDescr; }
+ bool is() { return typeDescr != nullptr; }
+ bool equals(const TypeDescriptionRef& other) const
+ {
+ return typeDescr && other.typeDescr
+ && typelib_typedescription_equals(typeDescr, other.typeDescr);
+ }
+
+private:
+ typelib_TypeDescription* typeDescr = nullptr;
+};
+
+std::optional<size_t> hashValue( size_t hash,
+ void const * val, typelib_TypeDescriptionReference * typeRef )
+{
+ o3tl::hash_combine( hash, typeRef->eTypeClass );
+ if (typeRef->eTypeClass == typelib_TypeClass_VOID) {
+ return hash;
+ }
+ assert(val != nullptr);
+
+ switch (typeRef->eTypeClass) {
+ case typelib_TypeClass_INTERFACE: {
+ return std::nullopt; // not implemented
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION: {
+ TypeDescription typeDescr( typeRef );
+ if (!typeDescr.is())
+ typeDescr.makeComplete();
+ if (!typeDescr.is())
+ return std::nullopt;
+
+ typelib_CompoundTypeDescription * compType =
+ reinterpret_cast< typelib_CompoundTypeDescription * >(
+ typeDescr.get() );
+ sal_Int32 nDescr = compType->nMembers;
+
+ if (compType->pBaseTypeDescription) {
+ std::optional<size_t> tmpHash = hashValue(
+ hash, val, reinterpret_cast<
+ typelib_TypeDescription * >(
+ compType->pBaseTypeDescription)->pWeakRef);
+ if(!tmpHash.has_value())
+ return std::nullopt;
+ hash = *tmpHash;
+ }
+
+ typelib_TypeDescriptionReference ** ppTypeRefs =
+ compType->ppTypeRefs;
+ sal_Int32 * memberOffsets = compType->pMemberOffsets;
+
+ for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
+ {
+ TypeDescriptionRef memberType( ppTypeRefs[ nPos ] );
+ if (!memberType.is())
+ return std::nullopt;
+
+ std::optional<size_t> tmpHash = hashValue( hash,
+ static_cast< char const * >(
+ val ) + memberOffsets[ nPos ],
+ memberType->pWeakRef );
+ if(!tmpHash.has_value())
+ return std::nullopt;
+ hash = *tmpHash;
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE: {
+ TypeDescriptionRef typeDescr( typeRef );
+ if (!typeDescr.is())
+ return std::nullopt;
+
+ typelib_TypeDescriptionReference * elementTypeRef =
+ reinterpret_cast<
+ typelib_IndirectTypeDescription * >(typeDescr.get())->pType;
+ TypeDescriptionRef elementTypeDescr( elementTypeRef );
+ if (!elementTypeDescr.is())
+ return std::nullopt;
+
+ sal_Int32 nElementSize = elementTypeDescr->nSize;
+ uno_Sequence * seq =
+ *static_cast< uno_Sequence * const * >(val);
+ sal_Int32 nElements = seq->nElements;
+
+ if (nElements > 0)
+ {
+ char const * pElements = seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ std::optional<size_t> tmpHash = hashValue( hash,
+ pElements + (nElementSize * nPos),
+ elementTypeDescr->pWeakRef );
+ if(!tmpHash.has_value())
+ return std::nullopt;
+ hash = *tmpHash;
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_ANY: {
+ uno_Any const * pAny = static_cast< uno_Any const * >(val);
+ return hashValue( hash, pAny->pData, pAny->pType );
+ }
+ case typelib_TypeClass_TYPE: {
+ OUString const & str = OUString::unacquired(
+ &(*static_cast<
+ typelib_TypeDescriptionReference * const * >(val)
+ )->pTypeName );
+ o3tl::hash_combine( hash, str.hashCode() );
+ break;
+ }
+ case typelib_TypeClass_STRING: {
+ OUString const & str = OUString::unacquired(
+ static_cast< rtl_uString * const * >(val) );
+ o3tl::hash_combine( hash, str.hashCode() );
+ break;
+ }
+ case typelib_TypeClass_ENUM: {
+ TypeDescription typeDescr( typeRef );
+ if (!typeDescr.is())
+ typeDescr.makeComplete();
+ if (!typeDescr.is())
+ return std::nullopt;
+
+ o3tl::hash_combine( hash, *static_cast< int const * >(val));
+ break;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ if (*static_cast< sal_Bool const * >(val))
+ o3tl::hash_combine( hash, true );
+ else
+ o3tl::hash_combine( hash, false );
+ break;
+ case typelib_TypeClass_CHAR: {
+ o3tl::hash_combine( hash, *static_cast< sal_Unicode const * >(val));
+ break;
+ }
+ case typelib_TypeClass_FLOAT:
+ o3tl::hash_combine( hash, *static_cast< float const * >(val) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ o3tl::hash_combine( hash, *static_cast< double const * >(val) );
+ break;
+ case typelib_TypeClass_BYTE:
+ o3tl::hash_combine( hash, *static_cast< sal_Int8 const * >(val) );
+ break;
+ case typelib_TypeClass_SHORT:
+ o3tl::hash_combine( hash, *static_cast< sal_Int16 const * >(val) );
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ o3tl::hash_combine( hash, *static_cast< sal_uInt16 const * >(val) );
+ break;
+ case typelib_TypeClass_LONG:
+ o3tl::hash_combine( hash, *static_cast< sal_Int32 const * >(val) );
+ break;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ o3tl::hash_combine( hash, *static_cast< sal_uInt32 const * >(val) );
+ break;
+ case typelib_TypeClass_HYPER:
+ o3tl::hash_combine( hash, *static_cast< sal_Int64 const * >(val) );
+ break;
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ o3tl::hash_combine( hash, *static_cast< sal_uInt64 const * >(val) );
+ break;
+// case typelib_TypeClass_UNKNOWN:
+// case typelib_TypeClass_SERVICE:
+// case typelib_TypeClass_MODULE:
+ default:
+ return std::nullopt;
+ }
+ return hash;
+}
+
+} // anon namespace
+
+
+std::optional<size_t> anyToHash( uno::Any const & value )
+{
+ size_t hash = 0;
+ return hashValue( hash, value.getValue(), value.getValueTypeRef());
+}
+
+} // namespace comphelper
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index f6bf0f10c9f7..c80c8206a87f 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -63,6 +63,8 @@ private:
// virtualdevice because that isn't safe to do at least for Gtk2
std::map<VclPtr<VirtualDevice>, VclPtr<OutputDevice>> maDeviceTemplates;
+ static bool isSizeSuitable(const VclPtr<VirtualDevice>& device, const Size& size);
+
public:
VDevBuffer();
virtual ~VDevBuffer() override;
@@ -101,6 +103,28 @@ VDevBuffer::~VDevBuffer()
}
}
+bool VDevBuffer::isSizeSuitable(const VclPtr<VirtualDevice>& device, const Size& rSizePixel)
+{
+ if (device->GetOutputWidthPixel() >= rSizePixel.getWidth()
+ && device->GetOutputHeightPixel() >= rSizePixel.getHeight())
+ {
+#if defined(UNX)
+ // HACK: See the small size handling in SvpSalVirtualDevice::CreateSurface().
+ // Make sure to not reuse a larger device when a small one should be preferred.
+ if (device->GetRenderBackendName() == "svp")
+ {
+ if (rSizePixel.getWidth() <= 32 && rSizePixel.getHeight() <= 32
+ && (device->GetOutputWidthPixel() > 32 || device->GetOutputHeightPixel() > 32))
+ {
+ return false;
+ }
+ }
+#endif
+ return true;
+ }
+ return false;
+}
+
VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel,
bool bTransparent)
{
@@ -127,9 +151,7 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
if (bOkay)
{
// found is valid
- const bool bCandidateOkay(
- a->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && a->buf->GetOutputHeightPixel() >= rSizePixel.getHeight());
+ const bool bCandidateOkay = isSizeSuitable(a->buf, rSizePixel);
if (bCandidateOkay)
{
@@ -154,16 +176,14 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
{
// found is invalid, use candidate
aFound = a;
- bOkay = aFound->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && aFound->buf->GetOutputHeightPixel() >= rSizePixel.getHeight();
+ bOkay = isSizeSuitable(aFound->buf, rSizePixel);
}
}
else
{
// none yet, use candidate
aFound = a;
- bOkay = aFound->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && aFound->buf->GetOutputHeightPixel() >= rSizePixel.getHeight();
+ bOkay = isSizeSuitable(aFound->buf, rSizePixel);
}
}
}
diff --git a/include/com/sun/star/uno/Sequence.hxx b/include/com/sun/star/uno/Sequence.hxx
index 26a51350815b..891f631aa9f3 100644
--- a/include/com/sun/star/uno/Sequence.hxx
+++ b/include/com/sun/star/uno/Sequence.hxx
@@ -138,6 +138,8 @@ inline bool Sequence< E >::operator == ( const Sequence & rSeq ) const
{
if (_pSequence == rSeq._pSequence)
return true;
+ if (_pSequence->nElements != rSeq._pSequence->nElements)
+ return false;
const Type & rType = ::cppu::getTypeFavourUnsigned( this );
return ::uno_type_equalData(
const_cast< Sequence * >( this ), rType.getTypeLibType(),
diff --git a/include/comphelper/anycompare.hxx b/include/comphelper/anycompare.hxx
index 782c7f19951f..d0dbd3cf8d49 100644
--- a/include/comphelper/anycompare.hxx
+++ b/include/comphelper/anycompare.hxx
@@ -212,6 +212,28 @@ namespace comphelper
} // namespace comphelper
+#include <comphelper/comphelperdllapi.h>
+
+#include <optional>
+
+namespace com::sun::star::uno
+{
+class Any;
+}
+
+namespace comphelper
+{
+/** Tries to get a hash value for an ANY value.
+
+ Not all cases may be implemented, in which case no value is returned.
+
+ @param value
+ ANY value
+ @return
+ hash of given ANY value, or not available
+*/
+COMPHELPER_DLLPUBLIC std::optional<size_t> anyToHash(css::uno::Any const& value);
+}
#endif // INCLUDED_COMPHELPER_ANYCOMPARE_HXX
diff --git a/include/svx/sdasitm.hxx b/include/svx/sdasitm.hxx
index e8db1996a9c8..b6ac7404b088 100644
--- a/include/svx/sdasitm.hxx
+++ b/include/svx/sdasitm.hxx
@@ -48,6 +48,16 @@ private:
css::uno::Sequence< css::beans::PropertyValue > aPropSeq;
+ // For fast comparisons keep a hash of the content, computed on demand
+ // (unusable state is if anyToHash() returns no hash).
+ enum HashState { Unknown, Valid, Unusable };
+ mutable HashState aHashState = HashState::Unknown;
+ mutable size_t aHash;
+
+ void SetPropSeq( const css::uno::Sequence< css::beans::PropertyValue >& rPropSeq );
+ inline void UpdateHash() const;
+ inline void InvalidateHash();
+
public:
SdrCustomShapeGeometryItem();
@@ -60,6 +70,9 @@ private:
SdrCustomShapeGeometryItem & operator =(SdrCustomShapeGeometryItem &&) = delete; // due to SfxPoolItem
virtual bool operator==( const SfxPoolItem& ) const override;
+ virtual bool operator<( const SfxPoolItem& ) const override;
+ virtual bool IsSortable() const override { return true; }
+
virtual bool GetPresentation(SfxItemPresentation ePresentation,
MapUnit eCoreMetric, MapUnit ePresentationMetric,
OUString &rText, const IntlWrapper&) const override;
diff --git a/include/svx/sdr/properties/defaultproperties.hxx b/include/svx/sdr/properties/defaultproperties.hxx
index e901278d3b3e..54d50ae611fd 100644
--- a/include/svx/sdr/properties/defaultproperties.hxx
+++ b/include/svx/sdr/properties/defaultproperties.hxx
@@ -92,7 +92,8 @@ namespace sdr::properties
virtual void SetObjectItemSet(const SfxItemSet& rSet) override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// get the installed StyleSheet
virtual SfxStyleSheet* GetStyleSheet() const override;
diff --git a/include/svx/sdr/properties/properties.hxx b/include/svx/sdr/properties/properties.hxx
index 600522981dc0..8ee9573b0972 100644
--- a/include/svx/sdr/properties/properties.hxx
+++ b/include/svx/sdr/properties/properties.hxx
@@ -162,7 +162,8 @@ namespace sdr::properties
// Set a new StyleSheet. Registers as listener at the StyleSheet to get knowledge
// of StyleSheet changes.
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) = 0;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) = 0;
// Get the installed StyleSheet.
virtual SfxStyleSheet* GetStyleSheet() const = 0;
diff --git a/include/svx/svdoashp.hxx b/include/svx/svdoashp.hxx
index 65540e93a9d5..bd0dba17deb5 100644
--- a/include/svx/svdoashp.hxx
+++ b/include/svx/svdoashp.hxx
@@ -132,6 +132,8 @@ protected:
// protected destructor
virtual ~SdrObjCustomShape() override;
+ virtual void InternalSetStyleSheet( SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr, bool bBroadcast ) override;
+
public:
bool UseNoFillStyle() const;
@@ -184,8 +186,6 @@ public:
virtual SdrGluePoint GetVertexGluePoint(sal_uInt16 nNum) const override;
- virtual void NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr ) override;
-
// special drag methods
virtual bool hasSpecialDrag() const override;
virtual bool beginSpecialDrag(SdrDragStat& rDrag) const override;
diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index 0960826d2c63..8843a8debf6e 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -623,7 +623,7 @@ public:
// if bDontRemoveHardAttr is false, set all attributes, which were set in the style sheet, to their default value
// if true, all hard attributes keep their values
void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr);
- virtual void NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr);
+ void NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr);
SfxStyleSheet* GetStyleSheet() const;
virtual bool HasTextEdit() const;
@@ -944,6 +944,8 @@ protected:
const SfxItemSet* getBackgroundFillSet() const;
+ virtual void InternalSetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr, bool bBroadcast);
+
private:
struct Impl;
std::unique_ptr<Impl> mpImpl;
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 7c5f28455b25..fc83a67740c8 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -280,6 +280,9 @@ public:
const AllSettings& GetSettings() const { return *mxSettings; }
SystemGraphicsData GetSystemGfxData() const;
+ OUString GetRenderBackendName() const;
+
+ // Used by the canvas module. Despite the name it does not always return true if Cairo is supported.
bool SupportsCairo() const;
/// Create Surface from given cairo surface
cairo::SurfaceSharedPtr CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const;
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index 6d6605c30c3a..c26903dfbd39 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -1382,6 +1382,7 @@ comphelper/source/misc/accessibletexthelper.cxx
comphelper/source/misc/accessiblewrapper.cxx
comphelper/source/misc/accimplaccess.cxx
comphelper/source/misc/anycompare.cxx
+comphelper/source/misc/anytohash.cxx
comphelper/source/misc/anytostring.cxx
comphelper/source/misc/asyncnotification.cxx
comphelper/source/misc/backupfilehelper.cxx
diff --git a/svx/inc/sdr/properties/attributeproperties.hxx b/svx/inc/sdr/properties/attributeproperties.hxx
index 9633257c5a63..3ec46eb9b62a 100644
--- a/svx/inc/sdr/properties/attributeproperties.hxx
+++ b/svx/inc/sdr/properties/attributeproperties.hxx
@@ -69,7 +69,8 @@ namespace sdr::properties
virtual ~AttributeProperties() override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// get the installed StyleSheet
virtual SfxStyleSheet* GetStyleSheet() const override;
diff --git a/svx/inc/sdr/properties/captionproperties.hxx b/svx/inc/sdr/properties/captionproperties.hxx
index c6f71529e181..c8f3fb4f30f5 100644
--- a/svx/inc/sdr/properties/captionproperties.hxx
+++ b/svx/inc/sdr/properties/captionproperties.hxx
@@ -47,7 +47,8 @@ namespace sdr::properties
virtual std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// force default attributes for a specific object type, called from
// DefaultProperties::GetObjectItemSet() if a new ItemSet is created
diff --git a/svx/inc/sdr/properties/circleproperties.hxx b/svx/inc/sdr/properties/circleproperties.hxx
index 2227817d1b49..348c57d1933d 100644
--- a/svx/inc/sdr/properties/circleproperties.hxx
+++ b/svx/inc/sdr/properties/circleproperties.hxx
@@ -47,7 +47,8 @@ namespace sdr::properties
virtual std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// force default attributes for a specific object type, called from
// DefaultProperties::GetObjectItemSet() if a new ItemSet is created
diff --git a/svx/inc/sdr/properties/connectorproperties.hxx b/svx/inc/sdr/properties/connectorproperties.hxx
index 8d6e14ffb64b..1577da3fb948 100644
--- a/svx/inc/sdr/properties/connectorproperties.hxx
+++ b/svx/inc/sdr/properties/connectorproperties.hxx
@@ -47,7 +47,8 @@ namespace sdr::properties
virtual std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
};
} // end of namespace sdr::properties
diff --git a/svx/inc/sdr/properties/customshapeproperties.hxx b/svx/inc/sdr/properties/customshapeproperties.hxx
index 8fa29e117bd7..0974a7facd37 100644
--- a/svx/inc/sdr/properties/customshapeproperties.hxx
+++ b/svx/inc/sdr/properties/customshapeproperties.hxx
@@ -56,7 +56,8 @@ namespace sdr::properties
public:
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// force default attributes for a specific object type, called from
// DefaultProperties::GetObjectItemSet() if a new ItemSet is created
diff --git a/svx/inc/sdr/properties/e3dsceneproperties.hxx b/svx/inc/sdr/properties/e3dsceneproperties.hxx
index e1192d022756..4606499bdffe 100644
--- a/svx/inc/sdr/properties/e3dsceneproperties.hxx
+++ b/svx/inc/sdr/properties/e3dsceneproperties.hxx
@@ -60,7 +60,8 @@ namespace sdr::properties
virtual void ClearMergedItem(const sal_uInt16 nWhich) override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// get the installed StyleSheet
virtual SfxStyleSheet* GetStyleSheet() const override;
diff --git a/svx/inc/sdr/properties/emptyproperties.hxx b/svx/inc/sdr/properties/emptyproperties.hxx
index 250c23deac0e..14af28d8a532 100644
--- a/svx/inc/sdr/properties/emptyproperties.hxx
+++ b/svx/inc/sdr/properties/emptyproperties.hxx
@@ -78,7 +78,8 @@ namespace sdr::properties
virtual void SetObjectItemSet(const SfxItemSet& rSet) override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// get the installed StyleSheet
virtual SfxStyleSheet* GetStyleSheet() const override;
diff --git a/svx/inc/sdr/properties/graphicproperties.hxx b/svx/inc/sdr/properties/graphicproperties.hxx
index 3a424f7e921d..39e4c66d237a 100644
--- a/svx/inc/sdr/properties/graphicproperties.hxx
+++ b/svx/inc/sdr/properties/graphicproperties.hxx
@@ -50,7 +50,8 @@ namespace sdr::properties
virtual std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// force default attributes for a specific object type, called from
// DefaultProperties::GetObjectItemSet() if a new ItemSet is created
diff --git a/svx/inc/sdr/properties/groupproperties.hxx b/svx/inc/sdr/properties/groupproperties.hxx
index 32fe503d1dd2..36ce508a8777 100644
--- a/svx/inc/sdr/properties/groupproperties.hxx
+++ b/svx/inc/sdr/properties/groupproperties.hxx
@@ -91,7 +91,8 @@ namespace sdr::properties
virtual void SetObjectItemSet(const SfxItemSet& rSet) override;
// set a new StyleSheet
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// get the local StyleSheet
virtual SfxStyleSheet* GetStyleSheet() const override;
diff --git a/svx/inc/sdr/properties/measureproperties.hxx b/svx/inc/sdr/properties/measureproperties.hxx
index 77cb253be45a..0927bc89b19c 100644
--- a/svx/inc/sdr/properties/measureproperties.hxx
+++ b/svx/inc/sdr/properties/measureproperties.hxx
@@ -47,7 +47,8 @@ namespace sdr::properties
virtual std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// force default attributes for a specific object type, called from
// DefaultProperties::GetObjectItemSet() if a new ItemSet is created
diff --git a/svx/inc/sdr/properties/pageproperties.hxx b/svx/inc/sdr/properties/pageproperties.hxx
index 7bd5c213fbc4..be85ed0e40f9 100644
--- a/svx/inc/sdr/properties/pageproperties.hxx
+++ b/svx/inc/sdr/properties/pageproperties.hxx
@@ -57,7 +57,8 @@ namespace sdr::properties
virtual SfxStyleSheet* GetStyleSheet() const override;
// set the installed StyleSheet
- virtual void SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// clear single item
virtual void ClearObjectItem(const sal_uInt16 nWhich = 0) override;
diff --git a/svx/inc/sdr/properties/rectangleproperties.hxx b/svx/inc/sdr/properties/rectangleproperties.hxx
index 1af85d786d9b..831e0b703c38 100644
--- a/svx/inc/sdr/properties/rectangleproperties.hxx
+++ b/svx/inc/sdr/properties/rectangleproperties.hxx
@@ -45,7 +45,8 @@ namespace sdr::properties
virtual std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
};
} // end of namespace sdr::properties
diff --git a/svx/inc/sdr/properties/textproperties.hxx b/svx/inc/sdr/properties/textproperties.hxx
index ea587a8996fb..70e5b2131381 100644
--- a/svx/inc/sdr/properties/textproperties.hxx
+++ b/svx/inc/sdr/properties/textproperties.hxx
@@ -59,7 +59,8 @@ namespace sdr::properties
virtual std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
// set a new StyleSheet and broadcast
- virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) override;
+ virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast) override;
// force default attributes for a specific object type, called from
// DefaultProperties::GetObjectItemSet() if a new ItemSet is created
diff --git a/svx/source/items/customshapeitem.cxx b/svx/source/items/customshapeitem.cxx
index 9a86a3bdb4aa..b5dbb2374f80 100644
--- a/svx/source/items/customshapeitem.cxx
+++ b/svx/source/items/customshapeitem.cxx
@@ -20,6 +20,8 @@
#include <sal/config.h>
#include <o3tl/any.hxx>
+#include <comphelper/anycompare.hxx>
+#include <comphelper/anycompare.hxx>
#include <svx/sdasitm.hxx>
#include <com/sun/star/beans/PropertyValue.hpp>
@@ -35,30 +37,7 @@ SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem()
SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem( const uno::Sequence< beans::PropertyValue >& rVal )
: SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )
{
- sal_Int32 i, j;
- aPropSeq = rVal;
-
- for ( i = 0; i < aPropSeq.getLength(); i++ )
- {
- beans::PropertyValue& rPropVal = aPropSeq[ i ];
- std::pair<PropertyHashMap::iterator, bool> const ret(
- aPropHashMap.insert(std::make_pair(rPropVal.Name, i)));
- assert(ret.second); // serious bug: duplicate xml attribute exported
- if (!ret.second)
- {
- throw uno::RuntimeException(
- "CustomShapeGeometry has duplicate property " + rPropVal.Name);
- }
- if (auto rPropSeq = o3tl::tryAccess<uno::Sequence<beans::PropertyValue>>(
- rPropVal.Value))
- {
- for ( j = 0; j < rPropSeq->getLength(); j++ )
- {
- beans::PropertyValue const & rPropVal2 = (*rPropSeq)[ j ];
- aPropPairHashMap[ PropertyPair( rPropVal.Name, rPropVal2.Name ) ] = j;
- }
- }
- }
+ SetPropSeq( rVal );
}
css::uno::Any* SdrCustomShapeGeometryItem::GetPropertyValueByName( const OUString& rPropName )
@@ -150,6 +129,7 @@ void SdrCustomShapeGeometryItem::SetPropertyValue( const css::beans::PropertyVal
aPropHashMap[ rPropVal.Name ] = nIndex;
}
+ InvalidateHash();
}
void SdrCustomShapeGeometryItem::SetPropertyValue( const OUString& rSequenceName, const css::beans::PropertyValue& rPropVal )
@@ -197,6 +177,7 @@ void SdrCustomShapeGeometryItem::SetPropertyValue( const OUString& rSequenceName
}
}
}
+ InvalidateHash();
}
void SdrCustomShapeGeometryItem::ClearPropertyValue( const OUString& rPropName )
@@ -232,17 +213,65 @@ void SdrCustomShapeGeometryItem::ClearPropertyValue( const OUString& rPropName )
aPropSeq.realloc( nLength - 1 );
}
aPropHashMap.erase( aHashIter ); // removing property from hashmap
+ InvalidateHash();
}
SdrCustomShapeGeometryItem::~SdrCustomShapeGeometryItem()
{
}
+
bool SdrCustomShapeGeometryItem::operator==( const SfxPoolItem& rCmp ) const
{
- bool bRet = SfxPoolItem::operator==( rCmp );
- if ( bRet )
- bRet = static_cast<const SdrCustomShapeGeometryItem&>(rCmp).aPropSeq == aPropSeq;
- return bRet;
+ if( !SfxPoolItem::operator==( rCmp ))
+ return false;
+ const SdrCustomShapeGeometryItem& other = static_cast<const SdrCustomShapeGeometryItem&>(rCmp);
+ // This is called often by SfxItemPool, and comparing uno sequences is relatively slow.
+ // So keep a hash of the sequence and if either of the sequences has a usable hash,
+ // compare using that.
+ UpdateHash();
+ other.UpdateHash();
+ if( aHashState != other.aHashState )
+ return false;
+ if( aHashState == HashState::Valid && aHash != other.aHash )
+ return false;
+
+ return aPropSeq == other.aPropSeq;
+}
+
+bool SdrCustomShapeGeometryItem::operator<( const SfxPoolItem& rCmp ) const
+{
+ assert(dynamic_cast<const SdrCustomShapeGeometryItem*>( &rCmp ));
+ const SdrCustomShapeGeometryItem& other = static_cast<const SdrCustomShapeGeometryItem&>(rCmp);
+ // Again, try to optimize by checking hashes first (this is operator< for sorting purposes,
+ // so the ordering can be somewhat arbitrary).
+ UpdateHash();
+ other.UpdateHash();
+ if( aHashState != other.aHashState )
+ return aHashState < other.aHashState;
+ if( aHashState == HashState::Valid )
+ return aHash < other.aHash;
+
+ return comphelper::anyLess( css::uno::makeAny( aPropSeq ),
+ css::uno::makeAny( other.aPropSeq ));
+}
+
+void SdrCustomShapeGeometryItem::UpdateHash() const
+{
+ if( aHashState != HashState::Unknown )
+ return;
+ std::optional< size_t > hash = comphelper::anyToHash( css::uno::makeAny( aPropSeq ));
+ if( hash.has_value())
+ {
+ aHash = *hash;
+ aHashState = HashState::Valid;
+ }
+ else
+ aHashState = HashState::Unusable;
+}
+
+void SdrCustomShapeGeometryItem::InvalidateHash()
+{
+ aHashState = HashState::Unknown;
}
bool SdrCustomShapeGeometryItem::GetPresentation(
@@ -273,24 +302,46 @@ bool SdrCustomShapeGeometryItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMember
bool SdrCustomShapeGeometryItem::PutValue( const uno::Any& rVal, sal_uInt8 /*nMemberId*/ )
{
- if ( ! ( rVal >>= aPropSeq ) )
+ css::uno::Sequence< css::beans::PropertyValue > propSeq;
+ if ( ! ( rVal >>= propSeq ) )
return false;
- for (sal_Int32 i = 0; i < aPropSeq.getLength(); ++i)
+ SetPropSeq( propSeq );
+ return true;
+}
+
+void SdrCustomShapeGeometryItem::SetPropSeq( const css::uno::Sequence< css::beans::PropertyValue >& rVal )
+{
+ if( aPropSeq == rVal )
+ return;
+
+ aPropSeq = rVal;
+ aPropHashMap.clear();
+ aPropPairHashMap.clear();
+ sal_Int32 i, j;
+
+ for ( i = 0; i < aPropSeq.getLength(); i++ )
{
- const auto& rName = aPropSeq[i].Name;
- bool isDuplicated = std::any_of(std::next(aPropSeq.begin(), i + 1), aPropSeq.end(),
- [&rName](const css::beans::PropertyValue& rProp) { return rProp.Name == rName; });
- if (isDuplicated)
+ beans::PropertyValue& rPropVal = aPropSeq[ i ];
+ std::pair<PropertyHashMap::iterator, bool> const ret(
+ aPropHashMap.insert(std::make_pair(rPropVal.Name, i)));
+ assert(ret.second); // serious bug: duplicate xml attribute exported
+ if (!ret.second)
{
- assert(false); // serious bug: duplicate xml attribute exported
- OUString const name(aPropSeq[i].Name);
- aPropSeq.realloc(0);
throw uno::RuntimeException(
- "CustomShapeGeometry has duplicate property " + name);
+ "CustomShapeGeometry has duplicate property " + rPropVal.Name);
+ }
+ if (auto rPropSeq = o3tl::tryAccess<uno::Sequence<beans::PropertyValue>>(
+ rPropVal.Value))
+ {
+ for ( j = 0; j < rPropSeq->getLength(); j++ )
+ {
+ beans::PropertyValue const & rPropVal2 = (*rPropSeq)[ j ];
+ aPropPairHashMap[ PropertyPair( rPropVal.Name, rPropVal2.Name ) ] = j;
+ }
}
}
- return true;
+ InvalidateHash();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/properties/attributeproperties.cxx b/svx/source/sdr/properties/attributeproperties.cxx
index 2dfd9e819981..8b5d6050e6a2 100644
--- a/svx/source/sdr/properties/attributeproperties.cxx
+++ b/svx/source/sdr/properties/attributeproperties.cxx
@@ -268,8 +268,7 @@ namespace sdr::properties
// problem with constructors and virtual functions in C++),
// thus DontRemoveHardAttr is not needed.
const_cast< AttributeProperties* >(this)->SetStyleSheet(
- mpStyleSheet,
- true);
+ mpStyleSheet, true, true);
}
}
@@ -360,7 +359,8 @@ namespace sdr::properties
}
}
- void AttributeProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void AttributeProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool /*bBroadcast*/)
{
// guarantee SfxItemSet existence
GetObjectItemSet();
diff --git a/svx/source/sdr/properties/captionproperties.cxx b/svx/source/sdr/properties/captionproperties.cxx
index d073aa91b91e..ea573c6a5252 100644
--- a/svx/source/sdr/properties/captionproperties.cxx
+++ b/svx/source/sdr/properties/captionproperties.cxx
@@ -73,10 +73,11 @@ namespace sdr::properties
RectangleProperties::ItemSetChanged(rSet);
}
- void CaptionProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void CaptionProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
// call parent (always first thing to do, may create the SfxItemSet)
- RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, bBroadcast);
// local changes
SdrCaptionObj& rObj = static_cast<SdrCaptionObj&>(GetSdrObject());
diff --git a/svx/source/sdr/properties/circleproperties.cxx b/svx/source/sdr/properties/circleproperties.cxx
index dab008ff6957..c40d5dfc87a3 100644
--- a/svx/source/sdr/properties/circleproperties.cxx
+++ b/svx/source/sdr/properties/circleproperties.cxx
@@ -77,10 +77,11 @@ namespace sdr::properties
rObj.ImpSetAttrToCircInfo();
}
- void CircleProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void CircleProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
// call parent (always first thing to do, may create the SfxItemSet)
- RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, bBroadcast);
// local changes
SdrCircObj& rObj = static_cast<SdrCircObj&>(GetSdrObject());
diff --git a/svx/source/sdr/properties/connectorproperties.cxx b/svx/source/sdr/properties/connectorproperties.cxx
index 97063011f79c..3323c40f47f3 100644
--- a/svx/source/sdr/properties/connectorproperties.cxx
+++ b/svx/source/sdr/properties/connectorproperties.cxx
@@ -74,10 +74,11 @@ namespace sdr::properties
rObj.ImpSetAttrToEdgeInfo();
}
- void ConnectorProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void ConnectorProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
// call parent (always first thing to do, may create the SfxItemSet)
- TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, bBroadcast);
// local changes
SdrEdgeObj& rObj = static_cast<SdrEdgeObj&>(GetSdrObject());
diff --git a/svx/source/sdr/properties/customshapeproperties.cxx b/svx/source/sdr/properties/customshapeproperties.cxx
index 07c893d1cf51..04b3c579bab7 100644
--- a/svx/source/sdr/properties/customshapeproperties.cxx
+++ b/svx/source/sdr/properties/customshapeproperties.cxx
@@ -161,10 +161,11 @@ namespace sdr::properties
UpdateTextFrameStatus(true);
}
- void CustomShapeProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void CustomShapeProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
// call parent (always first thing to do, may create the SfxItemSet)
- TextProperties::SetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr );
+ TextProperties::SetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr, bBroadcast );
// update bTextFrame and RenderGeometry
UpdateTextFrameStatus(true);
diff --git a/svx/source/sdr/properties/defaultproperties.cxx b/svx/source/sdr/properties/defaultproperties.cxx
index b12e7bd5b82d..7b4d9f5e6892 100644
--- a/svx/source/sdr/properties/defaultproperties.cxx
+++ b/svx/source/sdr/properties/defaultproperties.cxx
@@ -227,7 +227,8 @@ namespace sdr::properties
CleanupFillProperties(*mxItemSet);
}
- void DefaultProperties::SetStyleSheet(SfxStyleSheet* /*pNewStyleSheet*/, bool /*bDontRemoveHardAttr*/)
+ void DefaultProperties::SetStyleSheet(SfxStyleSheet* /*pNewStyleSheet*/, bool /*bDontRemoveHardAttr*/,
+ bool /*bBroadcast*/)
{
// no StyleSheet in DefaultProperties
}
diff --git a/svx/source/sdr/properties/e3dsceneproperties.cxx b/svx/source/sdr/properties/e3dsceneproperties.cxx
index 7635f32f806d..f911bc67aef6 100644
--- a/svx/source/sdr/properties/e3dsceneproperties.cxx
+++ b/svx/source/sdr/properties/e3dsceneproperties.cxx
@@ -230,7 +230,8 @@ namespace sdr::properties
}
}
- void E3dSceneProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void E3dSceneProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
const SdrObjList* pSub(static_cast<const E3dScene&>(GetSdrObject()).GetSubList());
OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
@@ -238,7 +239,10 @@ namespace sdr::properties
for(size_t a = 0; a < nCount; ++a)
{
- pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ if(bBroadcast)
+ pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ else
+ pSub->GetObj(a)->NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
}
}
diff --git a/svx/source/sdr/properties/emptyproperties.cxx b/svx/source/sdr/properties/emptyproperties.cxx
index 3837b23bfeec..c2043768e06a 100644
--- a/svx/source/sdr/properties/emptyproperties.cxx
+++ b/svx/source/sdr/properties/emptyproperties.cxx
@@ -103,7 +103,8 @@ namespace sdr::properties
assert(!"EmptyProperties::PostItemChange() should never be called");
}
- void EmptyProperties::SetStyleSheet(SfxStyleSheet* /*pNewStyleSheet*/, bool /*bDontRemoveHardAttr*/)
+ void EmptyProperties::SetStyleSheet(SfxStyleSheet* /*pNewStyleSheet*/, bool /*bDontRemoveHardAttr*/,
+ bool /*bBroadcast*/)
{
assert(!"EmptyProperties::SetStyleSheet() should never be called");
}
diff --git a/svx/source/sdr/properties/graphicproperties.cxx b/svx/source/sdr/properties/graphicproperties.cxx
index c7a9b6913ad0..f75e9bc08616 100644
--- a/svx/source/sdr/properties/graphicproperties.cxx
+++ b/svx/source/sdr/properties/graphicproperties.cxx
@@ -45,7 +45,7 @@ namespace sdr::properties
if(pStyleSheet)
{
// do not delete hard attributes when setting dsefault Style
- SetStyleSheet(pStyleSheet, true);
+ SetStyleSheet(pStyleSheet, true, true);
}
else
{
@@ -111,10 +111,11 @@ namespace sdr::properties
RectangleProperties::ItemSetChanged(rSet);
}
- void GraphicProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void GraphicProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
// call parent (always first thing to do, may create the SfxItemSet)
- RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, bBroadcast);
// local changes
SdrGrafObj& rObj = static_cast<SdrGrafObj&>(GetSdrObject());
diff --git a/svx/source/sdr/properties/groupproperties.cxx b/svx/source/sdr/properties/groupproperties.cxx
index 5f197c417688..176cce3dca53 100644
--- a/svx/source/sdr/properties/groupproperties.cxx
+++ b/svx/source/sdr/properties/groupproperties.cxx
@@ -243,7 +243,8 @@ namespace sdr::properties
return pRetval;
}
- void GroupProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void GroupProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
@@ -251,7 +252,10 @@ namespace sdr::properties
for(size_t a = 0; a < nCount; ++a)
{
- pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ if(bBroadcast)
+ pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ else
+ pSub->GetObj(a)->NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
}
}
diff --git a/svx/source/sdr/properties/measureproperties.cxx b/svx/source/sdr/properties/measureproperties.cxx
index e503c5710810..d1eef829ddf9 100644
--- a/svx/source/sdr/properties/measureproperties.cxx
+++ b/svx/source/sdr/properties/measureproperties.cxx
@@ -83,10 +83,11 @@ namespace sdr::properties
rObj.SetTextDirty();
}
- void MeasureProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void MeasureProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
// call parent (always first thing to do, may create the SfxItemSet)
- TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, bBroadcast);
// local changes
// get access to dimension line object
diff --git a/svx/source/sdr/properties/oleproperties.cxx b/svx/source/sdr/properties/oleproperties.cxx
index 2cdb55b70dde..587ff1d3f880 100644
--- a/svx/source/sdr/properties/oleproperties.cxx
+++ b/svx/source/sdr/properties/oleproperties.cxx
@@ -32,7 +32,7 @@ namespace sdr::properties
if(pStyleSheet)
{
// do not delete hard attributes when setting dsefault Style
- SetStyleSheet(pStyleSheet, true);
+ SetStyleSheet(pStyleSheet, true, true);
}
else
{
diff --git a/svx/source/sdr/properties/pageproperties.cxx b/svx/source/sdr/properties/pageproperties.cxx
index ed75133f929f..a0cb3dd10902 100644
--- a/svx/source/sdr/properties/pageproperties.cxx
+++ b/svx/source/sdr/properties/pageproperties.cxx
@@ -79,7 +79,8 @@ namespace sdr::properties
return nullptr;
}
- void PageProperties::SetStyleSheet(SfxStyleSheet* /*pStyleSheet*/, bool /*bDontRemoveHardAttr*/)
+ void PageProperties::SetStyleSheet(SfxStyleSheet* /*pStyleSheet*/, bool /*bDontRemoveHardAttr*/,
+ bool /*bBroadcast*/)
{
// override to legally ignore the StyleSheet here
}
diff --git a/svx/source/sdr/properties/properties.cxx b/svx/source/sdr/properties/properties.cxx
index 353cdc5ede36..70baecd06420 100644
--- a/svx/source/sdr/properties/properties.cxx
+++ b/svx/source/sdr/properties/properties.cxx
@@ -52,7 +52,7 @@ namespace sdr::properties
if(pDefaultStyleSheet != GetStyleSheet())
{
// do not delete hard attributes when setting dsefault Style
- SetStyleSheet(pDefaultStyleSheet, true);
+ SetStyleSheet(pDefaultStyleSheet, true, true);
}
}
diff --git a/svx/source/sdr/properties/rectangleproperties.cxx b/svx/source/sdr/properties/rectangleproperties.cxx
index 84b4fc17e23e..0f31491c0f8b 100644
--- a/svx/source/sdr/properties/rectangleproperties.cxx
+++ b/svx/source/sdr/properties/rectangleproperties.cxx
@@ -54,10 +54,11 @@ namespace sdr::properties
}
// set a new StyleSheet and broadcast
- void RectangleProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void RectangleProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
// call parent (always first thing to do, may create the SfxItemSet)
- TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, bBroadcast);
// local changes
SdrRectObj& rObj = static_cast<SdrRectObj&>(GetSdrObject());
diff --git a/svx/source/sdr/properties/textproperties.cxx b/svx/source/sdr/properties/textproperties.cxx
index de5c6765de75..a81ee01f1169 100644
--- a/svx/source/sdr/properties/textproperties.cxx
+++ b/svx/source/sdr/properties/textproperties.cxx
@@ -238,10 +238,11 @@ namespace sdr::properties
return static_cast<const SdrTextObj&>(GetSdrObject());
}
- void TextProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
+ void TextProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr,
+ bool bBroadcast)
{
// call parent (always first thing to do, may create the SfxItemSet)
- AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, bBroadcast);
// #i101556# StyleSheet has changed -> new version
SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 86819350e946..5eb1ea2eac31 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -2853,11 +2853,11 @@ SdrObjectUniquePtr SdrObjCustomShape::DoConvertToPolyObj(bool bBezier, bool bAdd
return pRetval;
}
-void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr )
+void SdrObjCustomShape::InternalSetStyleSheet( SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr, bool bBroadcast )
{
// #i40944#
InvalidateRenderGeometry();
- SdrObject::NbcSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr );
+ SdrObject::InternalSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr, bBroadcast );
}
void SdrObjCustomShape::handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage)
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 15b9cc6dcfcf..ef2deb6a4cb4 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -2237,7 +2237,7 @@ void SdrObject::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHar
if(m_pUserCall)
aBoundRect0 = GetLastBoundRect();
- NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ InternalSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, true);
SetChanged();
BroadcastObjectChange();
SendUserCall(SdrUserCallType::ChangeAttr, aBoundRect0);
@@ -2245,7 +2245,12 @@ void SdrObject::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHar
void SdrObject::NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
{
- GetProperties().SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ InternalSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, false);
+}
+
+void SdrObject::InternalSetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr, bool bBroadcast)
+{
+ GetProperties().SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr, bBroadcast);
}
// Broadcasting while setting attributes is managed by the AttrObj.
diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx
index eafaea0a1fa7..6e5125c5844c 100644
--- a/svx/source/table/cell.cxx
+++ b/svx/source/table/cell.cxx
@@ -650,7 +650,7 @@ void Cell::SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr )
if( mpProperties && (mpProperties->GetStyleSheet() != pStyleSheet) )
{
- mpProperties->SetStyleSheet( pStyleSheet, bDontRemoveHardAttr );
+ mpProperties->SetStyleSheet( pStyleSheet, bDontRemoveHardAttr, true );
}
}
diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx
index f8e9cb5e6874..4d82a46e50c4 100644
--- a/vcl/headless/svpvd.cxx
+++ b/vcl/headless/svpvd.cxx
@@ -76,29 +76,38 @@ void SvpSalVirtualDevice::CreateSurface(tools::Long nNewDX, tools::Long nNewDY,
cairo_surface_destroy(m_pSurface);
}
- if (pBuffer)
+ double fXScale, fYScale;
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ // Force scaling of the painting
+ fXScale = fYScale = comphelper::LibreOfficeKit::getDPIScale();
+ }
+ else
{
- double fXScale, fYScale;
- if (comphelper::LibreOfficeKit::isActive())
- {
- // Force scaling of the painting
- fXScale = fYScale = comphelper::LibreOfficeKit::getDPIScale();
- }
- else
- {
- dl_cairo_surface_get_device_scale(m_pRefSurface, &fXScale, &fYScale);
- nNewDX *= fXScale;
- nNewDY *= fYScale;
- }
+ dl_cairo_surface_get_device_scale(m_pRefSurface, &fXScale, &fYScale);
+ nNewDX *= fXScale;
+ nNewDY *= fYScale;
+ }
+ if (pBuffer)
+ {
m_pSurface = cairo_image_surface_create_for_data(pBuffer, CAIRO_FORMAT_ARGB32,
nNewDX, nNewDY, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, nNewDX));
-
+ dl_cairo_surface_set_device_scale(m_pSurface, fXScale, fYScale);
+ }
+ else if(nNewDX <= 32 && nNewDY <= 32)
+ {
+ // Force image-based surface if small. Small VirtualDevice instances are often used for small
+ // temporary bitmaps that will eventually have GetBitmap() called on them, which would cause
+ // X Server roundtrip with Xlib-based surface, which may be way more costly than doing the drawing
+ // in software (which should be fairly cheap for small surfaces anyway).
+ m_pSurface = cairo_surface_create_similar_image(m_pRefSurface, CAIRO_FORMAT_ARGB32, nNewDX, nNewDY);
dl_cairo_surface_set_device_scale(m_pSurface, fXScale, fYScale);
}
else
{
m_pSurface = cairo_surface_create_similar(m_pRefSurface, CAIRO_CONTENT_COLOR_ALPHA, nNewDX, nNewDY);
+ // Device scale is inherited in this case.
}
}
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index 71ec101f4dd1..60d945e3465c 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -231,6 +231,15 @@ SystemGraphicsData OutputDevice::GetSystemGfxData() const
return mpGraphics->GetGraphicsData();
}
+OUString OutputDevice::GetRenderBackendName() const
+{
+ if (!mpGraphics && !AcquireGraphics())
+ return {};
+ assert(mpGraphics);
+
+ return mpGraphics->getRenderBackendName();
+}
+
#if ENABLE_CAIRO_CANVAS
bool OutputDevice::SupportsCairo() const
--
2.31.1