diff options
Diffstat (limited to 'editeng/source/items/textitem.cxx')
-rw-r--r-- | editeng/source/items/textitem.cxx | 523 |
1 files changed, 391 insertions, 132 deletions
diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx index 32c269480c5a..b4fa77d59d6f 100644 --- a/editeng/source/items/textitem.cxx +++ b/editeng/source/items/textitem.cxx @@ -24,9 +24,11 @@ #include <sal/log.hxx> #include <o3tl/safeint.hxx> #include <osl/diagnose.h> +#include <comphelper/configuration.hxx> #include <unotools/fontdefs.hxx> #include <unotools/intlwrapper.hxx> #include <unotools/syslocale.hxx> +#include <utility> #include <vcl/outdev.hxx> #include <vcl/unohelp.hxx> #include <svtools/unitconv.hxx> @@ -76,7 +78,11 @@ #include <editeng/charreliefitem.hxx> #include <editeng/itemtype.hxx> #include <editeng/eerdll.hxx> +#include <docmodel/color/ComplexColorJSON.hxx> +#include <docmodel/uno/UnoComplexColor.hxx> +#include <docmodel/color/ComplexColor.hxx> #include <libxml/xmlwriter.h> +#include <unordered_map> using namespace ::com::sun::star; using namespace ::com::sun::star::text; @@ -97,12 +103,11 @@ SfxPoolItem* SvxKerningItem::CreateDefault() {return new SvxKerningItem(0, 0);} SfxPoolItem* SvxCaseMapItem::CreateDefault() {return new SvxCaseMapItem(SvxCaseMap::NotMapped, 0);} SfxPoolItem* SvxEscapementItem::CreateDefault() {return new SvxEscapementItem(0);} SfxPoolItem* SvxLanguageItem::CreateDefault() {return new SvxLanguageItem(LANGUAGE_GERMAN, 0);} -SfxPoolItem* SvxEmphasisMarkItem::CreateDefault() {return new SvxEmphasisMarkItem(FontEmphasisMark::NONE, 0);} -SfxPoolItem* SvxCharRotateItem::CreateDefault() {return new SvxCharRotateItem(0_deg10, false, 0);} -SfxPoolItem* SvxCharScaleWidthItem::CreateDefault() {return new SvxCharScaleWidthItem(100, 0);} +SfxPoolItem* SvxEmphasisMarkItem::CreateDefault() {return new SvxEmphasisMarkItem(FontEmphasisMark::NONE, TypedWhichId<SvxEmphasisMarkItem>(0));} +SfxPoolItem* SvxCharRotateItem::CreateDefault() {return new SvxCharRotateItem(0_deg10, false, TypedWhichId<SvxCharRotateItem>(0));} +SfxPoolItem* SvxCharScaleWidthItem::CreateDefault() {return new SvxCharScaleWidthItem(100, TypedWhichId<SvxCharScaleWidthItem>(0));} SfxPoolItem* SvxCharReliefItem::CreateDefault() {return new SvxCharReliefItem(FontRelief::NONE, 0);} - // class SvxFontListItem ------------------------------------------------- SvxFontListItem::SvxFontListItem( const FontList* pFontLst, @@ -154,47 +159,94 @@ bool SvxFontListItem::GetPresentation // class SvxFontItem ----------------------------------------------------- +typedef std::unordered_map<size_t, const SfxPoolItem*> SvxFontItemMap; + namespace { -sal_Int32 CompareTo(sal_Int32 nA, sal_Int32 nB) -{ - if (nA < nB) + class SvxFontItemInstanceManager : public ItemInstanceManager + { + SvxFontItemMap maRegistered; + + public: + SvxFontItemInstanceManager() + : ItemInstanceManager(typeid(SvxFontItem).hash_code()) + { + } + + private: + static size_t hashCode(const SfxPoolItem&); + + // standard interface, accessed exclusively + // by implCreateItemEntry/implCleanupItemEntry + virtual const SfxPoolItem* find(const SfxPoolItem&) const override; + virtual void add(const SfxPoolItem&) override; + virtual void remove(const SfxPoolItem&) override; + }; + + size_t SvxFontItemInstanceManager::hashCode(const SfxPoolItem& rItem) + { + const SvxFontItem& rFontItem(static_cast<const SvxFontItem&>(rItem)); + std::size_t seed(0); + o3tl::hash_combine(seed, rItem.Which()); + o3tl::hash_combine(seed, rFontItem.GetFamilyName().hashCode()); + o3tl::hash_combine(seed, rFontItem.GetStyleName().hashCode()); + o3tl::hash_combine(seed, rFontItem.GetFamily()); + o3tl::hash_combine(seed, rFontItem.GetPitch()); + o3tl::hash_combine(seed, rFontItem.GetCharSet()); + return seed; + } + + const SfxPoolItem* SvxFontItemInstanceManager::find(const SfxPoolItem& rItem) const { - return -1; + SvxFontItemMap::const_iterator aHit(maRegistered.find(hashCode(rItem))); + if (aHit != maRegistered.end()) + return aHit->second; + return nullptr; } - if (nA > nB) + void SvxFontItemInstanceManager::add(const SfxPoolItem& rItem) { - return 1; + maRegistered.insert({hashCode(rItem), &rItem}); } - return 0; -} + void SvxFontItemInstanceManager::remove(const SfxPoolItem& rItem) + { + maRegistered.erase(hashCode(rItem)); + } } -SvxFontItem::SvxFontItem( const sal_uInt16 nId ) : - SfxPoolItem( nId ) +ItemInstanceManager* SvxFontItem::getItemInstanceManager() const { - eFamily = FAMILY_SWISS; - ePitch = PITCH_VARIABLE; - eTextEncoding = RTL_TEXTENCODING_DONTKNOW; + static SvxFontItemInstanceManager aInstanceManager; + return &aInstanceManager; } - -SvxFontItem::SvxFontItem( const FontFamily eFam, const OUString& aName, - const OUString& aStName, const FontPitch eFontPitch, - const rtl_TextEncoding eFontTextEncoding, const sal_uInt16 nId ) : - - SfxPoolItem( nId ), - - aFamilyName(aName), - aStyleName(aStName) +SvxFontItem::SvxFontItem( + const sal_uInt16 nId) +: SfxPoolItem( nId ) +, aFamilyName() +, aStyleName() +, eFamily(FAMILY_SWISS) +, ePitch(PITCH_VARIABLE) +, eTextEncoding(RTL_TEXTENCODING_DONTKNOW) { - eFamily = eFam; - ePitch = eFontPitch; - eTextEncoding = eFontTextEncoding; } +SvxFontItem::SvxFontItem( + const FontFamily eFam, + OUString aName, + OUString aStName, + const FontPitch eFontPitch, + const rtl_TextEncoding eFontTextEncoding, + const sal_uInt16 nId) +: SfxPoolItem( nId ) +, aFamilyName(std::move(aName)) +, aStyleName(std::move(aStName)) +, eFamily(eFam) +, ePitch(eFontPitch) +, eTextEncoding(eFontTextEncoding) +{ +} bool SvxFontItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const { @@ -236,6 +288,7 @@ bool SvxFontItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) if ( !( rVal >>= aFontDescriptor )) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; aFamilyName = aFontDescriptor.Name; aStyleName = aFontDescriptor.StyleName; eFamily = static_cast<FontFamily>(aFontDescriptor.Family); @@ -248,6 +301,7 @@ bool SvxFontItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) OUString aStr; if(!(rVal >>= aStr)) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; aFamilyName = aStr; } break; @@ -256,6 +310,7 @@ bool SvxFontItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) OUString aStr; if(!(rVal >>= aStr)) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; aStyleName = aStr; } break; @@ -264,6 +319,7 @@ bool SvxFontItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) sal_Int16 nFamily = sal_Int16(); if(!(rVal >>= nFamily)) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; eFamily = static_cast<FontFamily>(nFamily); } break; @@ -272,6 +328,7 @@ bool SvxFontItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) sal_Int16 nSet = sal_Int16(); if(!(rVal >>= nSet)) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; eTextEncoding = static_cast<rtl_TextEncoding>(nSet); } break; @@ -280,6 +337,7 @@ bool SvxFontItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) sal_Int16 nPitch = sal_Int16(); if(!(rVal >>= nPitch)) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; ePitch = static_cast<FontPitch>(nPitch); } break; @@ -287,13 +345,58 @@ bool SvxFontItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) return true; } +void SvxFontItem::SetFamilyName(const OUString& rFamilyName) +{ + if (aFamilyName == rFamilyName) + return; + + ASSERT_CHANGE_REFCOUNTED_ITEM; + aFamilyName = rFamilyName; +} -bool SvxFontItem::operator==( const SfxPoolItem& rAttr ) const +void SvxFontItem::SetStyleName(const OUString &rStyleName) { - assert(SfxPoolItem::operator==(rAttr)); + if (aStyleName == rStyleName) + return; + + ASSERT_CHANGE_REFCOUNTED_ITEM; + aStyleName = rStyleName; +} + +void SvxFontItem::SetFamily(FontFamily _eFamily) +{ + if (eFamily == _eFamily) + return; + + ASSERT_CHANGE_REFCOUNTED_ITEM; + eFamily = _eFamily; +} + +void SvxFontItem::SetPitch(FontPitch _ePitch) +{ + if (ePitch == _ePitch) + return; + + ASSERT_CHANGE_REFCOUNTED_ITEM; + ePitch = _ePitch; +} - const SvxFontItem& rItem = static_cast<const SvxFontItem&>(rAttr); +void SvxFontItem::SetCharSet(rtl_TextEncoding _eEncoding) +{ + if (eTextEncoding == _eEncoding) + return; + + ASSERT_CHANGE_REFCOUNTED_ITEM; + eTextEncoding = _eEncoding; +} + +bool SvxFontItem::operator==( const SfxPoolItem& rAttr ) const +{ + if (this == &rAttr) + return true; + assert(SfxPoolItem::operator==(rAttr)); + const SvxFontItem& rItem(static_cast<const SvxFontItem&>(rAttr)); bool bRet = ( eFamily == rItem.eFamily && aFamilyName == rItem.aFamilyName && aStyleName == rItem.aStyleName ); @@ -306,37 +409,8 @@ bool SvxFontItem::operator==( const SfxPoolItem& rAttr ) const SAL_INFO( "editeng.items", "FontItem::operator==(): only pitch or rtl_TextEncoding different "); } } - return bRet; -} - -bool SvxFontItem::operator<(const SfxPoolItem& rCmp) const -{ - const auto& rOther = static_cast<const SvxFontItem&>(rCmp); - sal_Int32 nRet = GetFamilyName().compareTo(rOther.GetFamilyName()); - if (nRet != 0) - { - return nRet < 0; - } - - nRet = GetStyleName().compareTo(rOther.GetStyleName()); - if (nRet != 0) - { - return nRet < 0; - } - - nRet = CompareTo(GetFamily(), rOther.GetFamily()); - if (nRet != 0) - { - return nRet < 0; - } - nRet = CompareTo(GetPitch(), rOther.GetPitch()); - if (nRet != 0) - { - return nRet < 0; - } - - return GetCharSet() < rOther.GetCharSet(); + return bRet; } SvxFontItem* SvxFontItem::Clone( SfxItemPool * ) const @@ -371,6 +445,12 @@ void SvxFontItem::dumpAsXml(xmlTextWriterPtr pWriter) const // class SvxPostureItem -------------------------------------------------- +ItemInstanceManager* SvxPostureItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxPostureItem).hash_code()); + return &aInstanceManager; +} + SvxPostureItem::SvxPostureItem( const FontItalic ePosture, const sal_uInt16 nId ) : SfxEnumItem( nId, ePosture ) { @@ -439,6 +519,7 @@ bool SvxPostureItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) switch( nMemberId ) { case MID_ITALIC: + ASSERT_CHANGE_REFCOUNTED_ITEM; SetBoolValue(Any2Bool(rVal)); break; case MID_POSTURE: @@ -452,6 +533,7 @@ bool SvxPostureItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) eSlant = static_cast<awt::FontSlant>(nValue); } + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue(vcl::unohelper::ConvertFontSlant(eSlant)); } } @@ -470,6 +552,7 @@ bool SvxPostureItem::GetBoolValue() const void SvxPostureItem::SetBoolValue( bool bVal ) { + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue( bVal ? ITALIC_NORMAL : ITALIC_NONE ); } @@ -484,6 +567,12 @@ void SvxPostureItem::dumpAsXml(xmlTextWriterPtr pWriter) const // class SvxWeightItem --------------------------------------------------- +ItemInstanceManager* SvxWeightItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxWeightItem).hash_code()); + return &aInstanceManager; +} + SvxWeightItem::SvxWeightItem( const FontWeight eWght, const sal_uInt16 nId ) : SfxEnumItem( nId, eWght ) { @@ -504,6 +593,7 @@ bool SvxWeightItem::GetBoolValue() const void SvxWeightItem::SetBoolValue( bool bVal ) { + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue( bVal ? WEIGHT_BOLD : WEIGHT_NORMAL ); } @@ -547,7 +637,7 @@ OUString SvxWeightItem::GetValueTextByPos( sal_uInt16 nPos ) RID_SVXITEMS_WEIGHT_BLACK }; - static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_WEIGHTS) - 1 == WEIGHT_BLACK, "must match"); + static_assert(std::size(RID_SVXITEMS_WEIGHTS) - 1 == WEIGHT_BLACK, "must match"); assert(nPos <= sal_uInt16(WEIGHT_BLACK) && "enum overflow!" ); return EditResId(RID_SVXITEMS_WEIGHTS[nPos]); } @@ -575,6 +665,7 @@ bool SvxWeightItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) switch( nMemberId ) { case MID_BOLD : + ASSERT_CHANGE_REFCOUNTED_ITEM; SetBoolValue(Any2Bool(rVal)); break; case MID_WEIGHT: @@ -587,6 +678,7 @@ bool SvxWeightItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) return false; fValue = static_cast<float>(nValue); } + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue( vcl::unohelper::ConvertFontWeight(static_cast<float>(fValue)) ); } break; @@ -605,6 +697,12 @@ void SvxWeightItem::dumpAsXml(xmlTextWriterPtr pWriter) const // class SvxFontHeightItem ----------------------------------------------- +ItemInstanceManager* SvxFontHeightItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxFontHeightItem).hash_code()); + return &aInstanceManager; +} + SvxFontHeightItem::SvxFontHeightItem( const sal_uInt32 nSz, const sal_uInt16 nPrp, const sal_uInt16 nId ) : @@ -782,6 +880,7 @@ bool SvxFontHeightItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) if( fPoint < 0. || fPoint > 10000. ) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; nHeight = static_cast<tools::Long>( fPoint * 20.0 + 0.5 ); // Twips if (!bConvert) nHeight = convertTwipToMm100(nHeight); // Convert, if the item contains 1/100mm @@ -804,9 +903,17 @@ bool SvxFontHeightItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) return false; fPoint = static_cast<float>(nValue); } - if(fPoint < 0. || fPoint > 10000.) - return false; + if (fPoint < 0. || fPoint > 10000.) + return false; + static bool bFuzzing = comphelper::IsFuzzing(); + if (bFuzzing && fPoint > 120) + { + SAL_WARN("editeng.items", "SvxFontHeightItem ignoring font size of " << fPoint << " for performance"); + return false; + } + + ASSERT_CHANGE_REFCOUNTED_ITEM; nHeight = static_cast<tools::Long>( fPoint * 20.0 + 0.5 ); // Twips if (!bConvert) nHeight = convertTwipToMm100(nHeight); // Convert, if the item contains 1/100mm @@ -818,6 +925,7 @@ bool SvxFontHeightItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) if(!(rVal >>= nNew)) return true; + ASSERT_CHANGE_REFCOUNTED_ITEM; nHeight = lcl_GetRealHeight_Impl(nHeight, nProp, ePropUnit, bConvert); nHeight *= nNew; @@ -837,6 +945,7 @@ bool SvxFontHeightItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) return false; fValue = static_cast<float>(nValue); } + ASSERT_CHANGE_REFCOUNTED_ITEM; sal_Int16 nCoreDiffValue = static_cast<sal_Int16>(fValue * 20.); nHeight += bConvert ? nCoreDiffValue : convertTwipToMm100(nCoreDiffValue); nProp = static_cast<sal_uInt16>(static_cast<sal_Int16>(fValue)); @@ -877,6 +986,7 @@ bool SvxFontHeightItem::GetPresentation void SvxFontHeightItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) { + ASSERT_CHANGE_REFCOUNTED_ITEM; nHeight = static_cast<sal_uInt32>(BigInt::Scale( nHeight, nMult, nDiv )); } @@ -891,6 +1001,7 @@ void SvxFontHeightItem::SetHeight( sal_uInt32 nNewHeight, const sal_uInt16 nNewP { DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" ); + ASSERT_CHANGE_REFCOUNTED_ITEM; if( MapUnit::MapRelative != eUnit ) nHeight = nNewHeight + ::ItemToControl( short(nNewProp), eUnit, FieldUnit::TWIP ); @@ -908,6 +1019,7 @@ void SvxFontHeightItem::SetHeight( sal_uInt32 nNewHeight, sal_uInt16 nNewProp, { DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" ); + ASSERT_CHANGE_REFCOUNTED_ITEM; if( MapUnit::MapRelative != eMetric ) nHeight = nNewHeight + ::ControlToItem( ::ItemToControl(static_cast<short>(nNewProp), eMetric, @@ -935,7 +1047,8 @@ void SvxFontHeightItem::dumpAsXml(xmlTextWriterPtr pWriter) const // class SvxTextLineItem ------------------------------------------------ SvxTextLineItem::SvxTextLineItem( const FontLineStyle eSt, const sal_uInt16 nId ) - : SfxEnumItem( nId, eSt ), mColor( COL_TRANSPARENT ) + : SfxEnumItem(nId, eSt) + , maColor(COL_TRANSPARENT) { } @@ -954,6 +1067,7 @@ bool SvxTextLineItem::GetBoolValue() const void SvxTextLineItem::SetBoolValue( bool bVal ) { + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue( bVal ? LINESTYLE_SINGLE : LINESTYLE_NONE ); } @@ -977,8 +1091,8 @@ bool SvxTextLineItem::GetPresentation ) const { rText = GetValueTextByPos( GetValue() ); - if( !mColor.IsTransparent() ) - rText += cpDelim + ::GetColorString( mColor ); + if( !maColor.IsTransparent() ) + rText += cpDelim + ::GetColorString(maColor); return true; } @@ -1001,14 +1115,19 @@ bool SvxTextLineItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const rVal <<= static_cast<sal_Int16>(GetValue()); break; case MID_TL_COLOR: - rVal <<= mColor; + rVal <<= maColor; break; + case MID_TL_COMPLEX_COLOR: + { + auto xComplexColor = model::color::createXComplexColor(maComplexColor); + rVal <<= xComplexColor; + break; + } case MID_TL_HASCOLOR: - rVal <<= mColor.GetAlpha() == 255; + rVal <<= maColor.GetAlpha() == 255; break; } return true; - } bool SvxTextLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) @@ -1018,6 +1137,7 @@ bool SvxTextLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) switch(nMemberId) { case MID_TEXTLINED: + ASSERT_CHANGE_REFCOUNTED_ITEM; SetBoolValue(Any2Bool(rVal)); break; case MID_TL_STYLE: @@ -1026,7 +1146,10 @@ bool SvxTextLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) if(!(rVal >>= nValue)) bRet = false; else + { + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue(static_cast<FontLineStyle>(nValue)); + } } break; case MID_TL_COLOR: @@ -1038,14 +1161,29 @@ bool SvxTextLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) { // Keep transparence, because it contains the information // whether the font color or the stored color should be used - sal_uInt8 nAlpha = mColor.GetAlpha(); - mColor = nCol; - mColor.SetAlpha( nAlpha ); + ASSERT_CHANGE_REFCOUNTED_ITEM; + sal_uInt8 nAlpha = maColor.GetAlpha(); + maColor = nCol; + maColor.SetAlpha( nAlpha ); + } + } + break; + case MID_TL_COMPLEX_COLOR: + { + css::uno::Reference<css::util::XComplexColor> xComplexColor; + if (!(rVal >>= xComplexColor)) + return false; + + if (xComplexColor.is()) + { + ASSERT_CHANGE_REFCOUNTED_ITEM; + maComplexColor = model::color::getFromXComplexColor(xComplexColor); } } break; case MID_TL_HASCOLOR: - mColor.SetAlpha( Any2Bool( rVal ) ? 255 : 0 ); + ASSERT_CHANGE_REFCOUNTED_ITEM; + maColor.SetAlpha( Any2Bool( rVal ) ? 255 : 0 ); break; } return bRet; @@ -1054,11 +1192,17 @@ bool SvxTextLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) bool SvxTextLineItem::operator==( const SfxPoolItem& rItem ) const { return SfxEnumItem::operator==( rItem ) && - GetColor() == static_cast<const SvxTextLineItem&>(rItem).GetColor(); + maColor == static_cast<const SvxTextLineItem&>(rItem).maColor && + maComplexColor == static_cast<const SvxTextLineItem&>(rItem).maComplexColor; } // class SvxUnderlineItem ------------------------------------------------ +ItemInstanceManager* SvxUnderlineItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxUnderlineItem).hash_code()); + return &aInstanceManager; +} SvxUnderlineItem::SvxUnderlineItem( const FontLineStyle eSt, const sal_uInt16 nId ) : SvxTextLineItem( eSt, nId ) @@ -1094,13 +1238,19 @@ OUString SvxUnderlineItem::GetValueTextByPos( sal_uInt16 nPos ) const RID_SVXITEMS_UL_BOLDDASHDOTDOT, RID_SVXITEMS_UL_BOLDWAVE }; - static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_UL) - 1 == LINESTYLE_BOLDWAVE, "must match"); + static_assert(std::size(RID_SVXITEMS_UL) - 1 == LINESTYLE_BOLDWAVE, "must match"); assert(nPos <= sal_uInt16(LINESTYLE_BOLDWAVE) && "enum overflow!"); return EditResId(RID_SVXITEMS_UL[nPos]); } // class SvxOverlineItem ------------------------------------------------ +ItemInstanceManager* SvxOverlineItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxOverlineItem).hash_code()); + return &aInstanceManager; +} + SvxOverlineItem::SvxOverlineItem( const FontLineStyle eSt, const sal_uInt16 nId ) : SvxTextLineItem( eSt, nId ) { @@ -1135,13 +1285,19 @@ OUString SvxOverlineItem::GetValueTextByPos( sal_uInt16 nPos ) const RID_SVXITEMS_OL_BOLDDASHDOTDOT, RID_SVXITEMS_OL_BOLDWAVE }; - static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_OL) - 1 == LINESTYLE_BOLDWAVE, "must match"); + static_assert(std::size(RID_SVXITEMS_OL) - 1 == LINESTYLE_BOLDWAVE, "must match"); assert(nPos <= sal_uInt16(LINESTYLE_BOLDWAVE) && "enum overflow!"); return EditResId(RID_SVXITEMS_OL[nPos]); } // class SvxCrossedOutItem ----------------------------------------------- +ItemInstanceManager* SvxCrossedOutItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxCrossedOutItem).hash_code()); + return &aInstanceManager; +} + SvxCrossedOutItem::SvxCrossedOutItem( const FontStrikeout eSt, const sal_uInt16 nId ) : SfxEnumItem( nId, eSt ) { @@ -1162,6 +1318,7 @@ bool SvxCrossedOutItem::GetBoolValue() const void SvxCrossedOutItem::SetBoolValue( bool bVal ) { + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue( bVal ? STRIKEOUT_SINGLE : STRIKEOUT_NONE ); } @@ -1200,7 +1357,7 @@ OUString SvxCrossedOutItem::GetValueTextByPos( sal_uInt16 nPos ) RID_SVXITEMS_STRIKEOUT_SLASH, RID_SVXITEMS_STRIKEOUT_X }; - static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_STRIKEOUT) - 1 == STRIKEOUT_X, "must match"); + static_assert(std::size(RID_SVXITEMS_STRIKEOUT) - 1 == STRIKEOUT_X, "must match"); assert(nPos <= sal_uInt16(STRIKEOUT_X) && "enum overflow!"); return EditResId(RID_SVXITEMS_STRIKEOUT[nPos]); } @@ -1233,6 +1390,7 @@ bool SvxCrossedOutItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) sal_Int32 nValue = 0; if(!(rVal >>= nValue)) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue(static_cast<FontStrikeout>(nValue)); } break; @@ -1355,21 +1513,20 @@ bool SvxContourItem::GetPresentation // class SvxColorItem ---------------------------------------------------- SvxColorItem::SvxColorItem( const sal_uInt16 nId ) : SfxPoolItem(nId), - mColor( COL_BLACK ), - maThemeIndex(-1), - maTintShade(0), - mnLumMod(10000), - mnLumOff(0) + mColor( COL_BLACK ) { } SvxColorItem::SvxColorItem( const Color& rCol, const sal_uInt16 nId ) : SfxPoolItem( nId ), - mColor( rCol ), - maThemeIndex(-1), - maTintShade(0), - mnLumMod(10000), - mnLumOff(0) + mColor( rCol ) +{ +} + +SvxColorItem::SvxColorItem(Color const& rColor, model::ComplexColor const& rComplexColor, const sal_uInt16 nId) + : SfxPoolItem(nId) + , mColor(rColor) + , maComplexColor(rComplexColor) { } @@ -1383,10 +1540,7 @@ bool SvxColorItem::operator==( const SfxPoolItem& rAttr ) const const SvxColorItem& rColorItem = static_cast<const SvxColorItem&>(rAttr); return mColor == rColorItem.mColor && - maThemeIndex == rColorItem.maThemeIndex && - maTintShade == rColorItem.maTintShade && - mnLumMod == rColorItem.mnLumMod && - mnLumOff == rColorItem.mnLumOff; + maComplexColor == rColorItem.maComplexColor; } bool SvxColorItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const @@ -1407,24 +1561,56 @@ bool SvxColorItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const } case MID_COLOR_THEME_INDEX: { - rVal <<= maThemeIndex; + rVal <<= sal_Int16(maComplexColor.getThemeColorType()); break; } case MID_COLOR_TINT_OR_SHADE: { - rVal <<= maTintShade; + sal_Int16 nValue = 0; + for (auto const& rTransform : maComplexColor.getTransformations()) + { + if (rTransform.meType == model::TransformationType::Tint) + nValue = rTransform.mnValue; + else if (rTransform.meType == model::TransformationType::Shade) + nValue = -rTransform.mnValue; + } + rVal <<= nValue; break; } case MID_COLOR_LUM_MOD: { - rVal <<= mnLumMod; + sal_Int16 nValue = 10000; + for (auto const& rTransform : maComplexColor.getTransformations()) + { + if (rTransform.meType == model::TransformationType::LumMod) + nValue = rTransform.mnValue; + } + rVal <<= nValue; break; } case MID_COLOR_LUM_OFF: { - rVal <<= mnLumOff; + sal_Int16 nValue = 0; + for (auto const& rTransform : maComplexColor.getTransformations()) + { + if (rTransform.meType == model::TransformationType::LumOff) + nValue = rTransform.mnValue; + } + rVal <<= nValue; break; } + case MID_COMPLEX_COLOR_JSON: + { + rVal <<= OStringToOUString(model::color::convertToJSON(maComplexColor), RTL_TEXTENCODING_UTF8); + break; + } + case MID_COMPLEX_COLOR: + { + auto xComplexColor = model::color::createXComplexColor(maComplexColor); + rVal <<= xComplexColor; + break; + } + case MID_COLOR_RGB: default: { rVal <<= mColor; @@ -1460,36 +1646,74 @@ bool SvxColorItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) sal_Int16 nIndex = -1; if (!(rVal >>= nIndex)) return false; - maThemeIndex = nIndex; + maComplexColor.setThemeColor(model::convertToThemeColorType(nIndex)); } break; case MID_COLOR_TINT_OR_SHADE: { - sal_Int16 nTintShade = -1; + sal_Int16 nTintShade = 0; if (!(rVal >>= nTintShade)) return false; - maTintShade = nTintShade; + + maComplexColor.removeTransformations(model::TransformationType::Tint); + maComplexColor.removeTransformations(model::TransformationType::Shade); + + if (nTintShade > 0) + maComplexColor.addTransformation({model::TransformationType::Tint, nTintShade}); + else if (nTintShade < 0) + { + sal_Int16 nShade = o3tl::narrowing<sal_Int16>(-nTintShade); + maComplexColor.addTransformation({model::TransformationType::Shade, nShade}); + } } break; case MID_COLOR_LUM_MOD: { - sal_Int16 nLumMod = -1; + sal_Int16 nLumMod = 10000; if (!(rVal >>= nLumMod)) return false; - mnLumMod = nLumMod; + maComplexColor.removeTransformations(model::TransformationType::LumMod); + maComplexColor.addTransformation({model::TransformationType::LumMod, nLumMod}); } break; case MID_COLOR_LUM_OFF: { - sal_Int16 nLumOff = -1; + sal_Int16 nLumOff = 0; if (!(rVal >>= nLumOff)) return false; - mnLumOff = nLumOff; + maComplexColor.removeTransformations(model::TransformationType::LumOff); + maComplexColor.addTransformation({model::TransformationType::LumOff, nLumOff}); } break; + case MID_COMPLEX_COLOR_JSON: + { + OUString sComplexColorJson; + if (!(rVal >>= sComplexColorJson)) + return false; + + if (sComplexColorJson.isEmpty()) + return false; + + OString aJSON = OUStringToOString(sComplexColorJson, RTL_TEXTENCODING_ASCII_US); + if (!model::color::convertFromJSON(aJSON, maComplexColor)) + return false; + } + break; + case MID_COMPLEX_COLOR: + { + css::uno::Reference<css::util::XComplexColor> xComplexColor; + if (!(rVal >>= xComplexColor)) + return false; + + if (xComplexColor.is()) + maComplexColor = model::color::getFromXComplexColor(xComplexColor); + } + break; + case MID_COLOR_RGB: default: { - return rVal >>= mColor; + if (!(rVal >>= mColor)) + return false; } break; } @@ -1526,14 +1750,25 @@ void SvxColorItem::dumpAsXml(xmlTextWriterPtr pWriter) const IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag()); GetPresentation( SfxItemPresentation::Complete, MapUnit::Map100thMM, MapUnit::Map100thMM, aStr, aIntlWrapper); (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(OUStringToOString(aStr, RTL_TEXTENCODING_UTF8).getStr())); - (void)xmlTextWriterEndElement(pWriter); -} + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("complex-color")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("type"), + BAD_CAST(OString::number(sal_Int16(maComplexColor.getType())).getStr())); -void SvxColorItem::SetValue( const Color& rNewCol ) -{ - mColor = rNewCol; + for (auto const& rTransform : maComplexColor.getTransformations()) + { + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("transformation")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("type"), + BAD_CAST(OString::number(sal_Int16(rTransform.meType)).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), + BAD_CAST(OString::number(rTransform.mnValue).getStr())); + (void)xmlTextWriterEndElement(pWriter); + } + + (void)xmlTextWriterEndElement(pWriter); + + (void)xmlTextWriterEndElement(pWriter); } // class SvxKerningItem -------------------------------------------------- @@ -1655,7 +1890,7 @@ OUString SvxCaseMapItem::GetValueTextByPos( sal_uInt16 nPos ) RID_SVXITEMS_CASEMAP_SMALLCAPS }; - static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_CASEMAP) == size_t(SvxCaseMap::End), "must match"); + static_assert(std::size(RID_SVXITEMS_CASEMAP) == size_t(SvxCaseMap::End), "must match"); assert(nPos < sal_uInt16(SvxCaseMap::End) && "enum overflow!"); return EditResId(RID_SVXITEMS_CASEMAP[nPos]); } @@ -1775,7 +2010,7 @@ OUString SvxEscapementItem::GetValueTextByPos( sal_uInt16 nPos ) RID_SVXITEMS_ESCAPEMENT_SUB }; - static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_ESCAPEMENT) == size_t(SvxEscapement::End), "must match"); + static_assert(std::size(RID_SVXITEMS_ESCAPEMENT) == size_t(SvxEscapement::End), "must match"); assert(nPos < sal_uInt16(SvxEscapement::End) && "enum overflow!"); return EditResId(RID_SVXITEMS_ESCAPEMENT[nPos]); } @@ -1859,6 +2094,12 @@ bool SvxEscapementItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) // class SvxLanguageItem ------------------------------------------------- +ItemInstanceManager* SvxLanguageItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxLanguageItem).hash_code()); + return &aInstanceManager; +} + SvxLanguageItem::SvxLanguageItem( const LanguageType eLang, const sal_uInt16 nId ) : SvxLanguageItem_Base( nId , eLang ) { @@ -1918,6 +2159,7 @@ bool SvxLanguageItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) if(!(rVal >>= nValue)) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue(LanguageType(nValue)); } break; @@ -1927,6 +2169,7 @@ bool SvxLanguageItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) if(!(rVal >>= aLocale)) return false; + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue( LanguageTag::convertToLanguageType( aLocale, false)); } break; @@ -1936,8 +2179,8 @@ bool SvxLanguageItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) // class SvxNoHyphenItem ------------------------------------------------- -SvxNoHyphenItem::SvxNoHyphenItem( const sal_uInt16 nId ) : - SfxBoolItem( nId , true ) +SvxNoHyphenItem::SvxNoHyphenItem( const bool bNoHyphen, const sal_uInt16 nId ) : + SfxBoolItem( nId, bNoHyphen ) { } @@ -1954,8 +2197,12 @@ bool SvxNoHyphenItem::GetPresentation OUString& rText, const IntlWrapper& /*rIntl*/ ) const { - rText.clear(); - return false; + if ( GetValue() ) + rText = EditResId(RID_SVXITEMS_NOHYPHENATION_TRUE); + else + rText.clear(); + + return GetValue(); } /* @@ -1995,8 +2242,14 @@ bool SvxBlinkItem::GetPresentation // class SvxEmphaisMarkItem --------------------------------------------------- +ItemInstanceManager* SvxEmphasisMarkItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxEmphasisMarkItem).hash_code()); + return &aInstanceManager; +} + SvxEmphasisMarkItem::SvxEmphasisMarkItem( const FontEmphasisMark nValue, - const sal_uInt16 nId ) + TypedWhichId<SvxEmphasisMarkItem> nId ) : SfxUInt16Item( nId, static_cast<sal_uInt16>(nValue) ) { } @@ -2087,6 +2340,7 @@ bool SvxEmphasisMarkItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) case FontEmphasis::ACCENT_BELOW: nMark = FontEmphasisMark::Accent|FontEmphasisMark::PosBelow; break; default: return false; } + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue( static_cast<sal_Int16>(nMark) ); } break; @@ -2207,7 +2461,7 @@ bool SvxTwoLinesItem::GetPresentation( SfxItemPresentation /*ePres*/, |* class SvxTextRotateItem *************************************************************************/ -SvxTextRotateItem::SvxTextRotateItem(Degree10 nValue, const sal_uInt16 nW) +SvxTextRotateItem::SvxTextRotateItem(Degree10 nValue, TypedWhichId<SvxTextRotateItem> nW) : SfxUInt16Item(nW, nValue.get()) { } @@ -2286,7 +2540,7 @@ void SvxTextRotateItem::dumpAsXml(xmlTextWriterPtr pWriter) const SvxCharRotateItem::SvxCharRotateItem( Degree10 nValue, bool bFitIntoLine, - const sal_uInt16 nW ) + TypedWhichId<SvxCharRotateItem> nW ) : SvxTextRotateItem(nValue, nW), bFitToLine( bFitIntoLine ) { } @@ -2375,7 +2629,7 @@ void SvxCharRotateItem::dumpAsXml(xmlTextWriterPtr pWriter) const *************************************************************************/ SvxCharScaleWidthItem::SvxCharScaleWidthItem( sal_uInt16 nValue, - const sal_uInt16 nW ) + TypedWhichId<SvxCharScaleWidthItem> nW ) : SfxUInt16Item( nW, nValue ) { } @@ -2428,6 +2682,12 @@ bool SvxCharScaleWidthItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMemberId*/ |* class SvxCharReliefItem *************************************************************************/ +ItemInstanceManager* SvxCharReliefItem::getItemInstanceManager() const +{ + static DefaultItemInstanceManager aInstanceManager(typeid(SvxCharReliefItem).hash_code()); + return &aInstanceManager; +} + SvxCharReliefItem::SvxCharReliefItem( FontRelief eValue, const sal_uInt16 nId ) : SfxEnumItem( nId, eValue ) @@ -2448,13 +2708,13 @@ static TranslateId RID_SVXITEMS_RELIEF[] = OUString SvxCharReliefItem::GetValueTextByPos(sal_uInt16 nPos) { - assert(nPos < SAL_N_ELEMENTS(RID_SVXITEMS_RELIEF) && "enum overflow"); + assert(nPos < std::size(RID_SVXITEMS_RELIEF) && "enum overflow"); return EditResId(RID_SVXITEMS_RELIEF[nPos]); } sal_uInt16 SvxCharReliefItem::GetValueCount() const { - return SAL_N_ELEMENTS(RID_SVXITEMS_RELIEF) - 1; + return std::size(RID_SVXITEMS_RELIEF) - 1; } bool SvxCharReliefItem::GetPresentation @@ -2481,7 +2741,10 @@ bool SvxCharReliefItem::PutValue( const css::uno::Any& rVal, sal_Int16 nVal = -1; rVal >>= nVal; if(nVal >= 0 && nVal <= sal_Int16(FontRelief::Engraved)) + { + ASSERT_CHANGE_REFCOUNTED_ITEM; SetValue( static_cast<FontRelief>(nVal) ); + } else bRet = false; } @@ -2597,21 +2860,17 @@ void SvxScriptSetItem::PutItemForScriptType( SvtScriptType nScriptType, sal_uInt16 nLatin, nAsian, nComplex; GetWhichIds( nLatin, nAsian, nComplex ); - std::unique_ptr<SfxPoolItem> pCpy(rItem.Clone()); if( SvtScriptType::LATIN & nScriptType ) { - pCpy->SetWhich( nLatin ); - GetItemSet().Put( *pCpy ); + GetItemSet().Put( rItem.CloneSetWhich(nLatin) ); } if( SvtScriptType::ASIAN & nScriptType ) { - pCpy->SetWhich( nAsian ); - GetItemSet().Put( *pCpy ); + GetItemSet().Put( rItem.CloneSetWhich(nAsian) ); } if( SvtScriptType::COMPLEX & nScriptType ) { - pCpy->SetWhich( nComplex ); - GetItemSet().Put( *pCpy ); + GetItemSet().Put( rItem.CloneSetWhich(nComplex) ); } } @@ -2619,9 +2878,9 @@ void SvxScriptSetItem::GetWhichIds( sal_uInt16 nSlotId, const SfxItemSet& rSet, { const SfxItemPool& rPool = *rSet.GetPool(); GetSlotIds( nSlotId, rLatin, rAsian, rComplex ); - rLatin = rPool.GetWhich( rLatin ); - rAsian = rPool.GetWhich( rAsian ); - rComplex = rPool.GetWhich( rComplex ); + rLatin = rPool.GetWhichIDFromSlotID( rLatin ); + rAsian = rPool.GetWhichIDFromSlotID( rAsian ); + rComplex = rPool.GetWhichIDFromSlotID( rComplex ); } void SvxScriptSetItem::GetWhichIds( sal_uInt16& rLatin, sal_uInt16& rAsian, |