From c27946fb157fe46fbfaefbe93f2c6794b1af4411 Mon Sep 17 00:00:00 2001 From: Sarper Akdemir Date: Wed, 15 Mar 2023 19:25:03 +0300 Subject: [PATCH] tdf#150020 pptx import: handle algn for outerShdw Introduces RectangleAlignmentItem that holds a value of the enum model::RectangleAlignment. Introduces SDRATTR_SHADOWALIGNMENT that holds alignment for a shadow. Implements import of algn for outerShdw. Makes the alignment considered while the shadow is being scaled. Also adds a unit test that covers this. Change-Id: I8f4eaed5f0d9428a7f405c65f19237f9e70ca151 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148934 Tested-by: Jenkins Reviewed-by: Sarper Akdemir --- .../source/attribute/sdrshadowattribute.cxx | 13 ++++- include/docmodel/theme/FormatScheme.hxx | 2 + .../attribute/sdrshadowattribute.hxx | 6 +++ include/editeng/unoprnms.hxx | 1 + include/svx/RectangleAlignmentItem.hxx | 42 ++++++++++++++++ include/svx/svddef.hxx | 4 +- include/svx/unoshprp.hxx | 3 +- oox/source/drawingml/effectproperties.cxx | 5 ++ oox/source/drawingml/effectproperties.hxx | 5 ++ .../drawingml/effectpropertiescontext.cxx | 1 + oox/source/token/properties.txt | 1 + svx/Library_svxcore.mk | 1 + .../unit/data/tdf150020-shadow-alignment.pptx | Bin 0 -> 51529 bytes svx/qa/unit/sdr.cxx | 47 ++++++++++++++++++ svx/source/items/RectangleAlignmentItem.cxx | 31 ++++++++++++ .../sdr/primitive2d/sdrattributecreator.cxx | 5 +- .../sdr/primitive2d/sdrdecompositiontools.cxx | 45 ++++++++++++----- svx/source/svdraw/svdattr.cxx | 4 ++ sw/qa/extras/layout/layout.cxx | 17 +++++-- 19 files changed, 213 insertions(+), 20 deletions(-) create mode 100644 include/svx/RectangleAlignmentItem.hxx create mode 100644 svx/qa/unit/data/tdf150020-shadow-alignment.pptx create mode 100644 svx/source/items/RectangleAlignmentItem.cxx diff --git a/drawinglayer/source/attribute/sdrshadowattribute.cxx b/drawinglayer/source/attribute/sdrshadowattribute.cxx index 6e046f1f07c7..1eb1b3ea687c 100644 --- a/drawinglayer/source/attribute/sdrshadowattribute.cxx +++ b/drawinglayer/source/attribute/sdrshadowattribute.cxx @@ -20,6 +20,7 @@ #include #include #include +#include namespace drawinglayer::attribute @@ -32,6 +33,7 @@ namespace drawinglayer::attribute basegfx::B2DVector maSize; // [0.0 .. 2.0] double mfTransparence; // [0.0 .. 1.0], 0.0==no transp. sal_Int32 mnBlur; // [0 .. 180], radius of the blur + model::RectangleAlignment meAlignment{model::RectangleAlignment::Unset}; // alignment of the shadow basegfx::BColor maColor; // color of shadow ImpSdrShadowAttribute( @@ -39,11 +41,13 @@ namespace drawinglayer::attribute const basegfx::B2DVector& rSize, double fTransparence, sal_Int32 nBlur, + model::RectangleAlignment eAlignment, const basegfx::BColor& rColor) : maOffset(rOffset), maSize(rSize), mfTransparence(fTransparence), mnBlur(nBlur), + meAlignment(eAlignment), maColor(rColor) { } @@ -67,6 +71,7 @@ namespace drawinglayer::attribute && getSize() == rCandidate.getSize() && getTransparence() == rCandidate.getTransparence() && getBlur() == rCandidate.getBlur() + && meAlignment == rCandidate.meAlignment && getColor() == rCandidate.getColor()); } }; @@ -86,9 +91,10 @@ namespace drawinglayer::attribute const basegfx::B2DVector& rSize, double fTransparence, sal_Int32 nBlur, + model::RectangleAlignment eAlignment, const basegfx::BColor& rColor) : mpSdrShadowAttribute(ImpSdrShadowAttribute( - rOffset, rSize, fTransparence,nBlur, rColor)) + rOffset, rSize, fTransparence, nBlur, eAlignment, rColor)) { } @@ -141,6 +147,11 @@ namespace drawinglayer::attribute return mpSdrShadowAttribute->getBlur(); } + model::RectangleAlignment SdrShadowAttribute::getAlignment() const + { + return mpSdrShadowAttribute->meAlignment; + } + const basegfx::BColor& SdrShadowAttribute::getColor() const { return mpSdrShadowAttribute->getColor(); diff --git a/include/docmodel/theme/FormatScheme.hxx b/include/docmodel/theme/FormatScheme.hxx index e207d9935432..feec16ee187f 100644 --- a/include/docmodel/theme/FormatScheme.hxx +++ b/include/docmodel/theme/FormatScheme.hxx @@ -306,6 +306,8 @@ enum class RectangleAlignment Bottom, BottomRight }; +constexpr sal_uInt16 RECTANGLE_ALIGNMENT_COUNT + = static_cast(RectangleAlignment::BottomRight) + 1; enum class ColorEffectType { diff --git a/include/drawinglayer/attribute/sdrshadowattribute.hxx b/include/drawinglayer/attribute/sdrshadowattribute.hxx index ffe249498db2..ab2c045e49bb 100644 --- a/include/drawinglayer/attribute/sdrshadowattribute.hxx +++ b/include/drawinglayer/attribute/sdrshadowattribute.hxx @@ -31,6 +31,10 @@ namespace basegfx { class B2DVector; } +namespace model { + enum class RectangleAlignment; +} + namespace drawinglayer::attribute { class ImpSdrShadowAttribute; } @@ -53,6 +57,7 @@ namespace drawinglayer::attribute const basegfx::B2DVector& rSize, double fTransparence, sal_Int32 nBlur, + model::RectangleAlignment eAlignment, const basegfx::BColor& rColor); SdrShadowAttribute(); SdrShadowAttribute(const SdrShadowAttribute&); @@ -72,6 +77,7 @@ namespace drawinglayer::attribute const basegfx::B2DVector& getSize() const; double getTransparence() const; sal_Int32 getBlur() const; + model::RectangleAlignment getAlignment() const; const basegfx::BColor& getColor() const; }; diff --git a/include/editeng/unoprnms.hxx b/include/editeng/unoprnms.hxx index 1ca19c3f5121..63d52d7537a6 100644 --- a/include/editeng/unoprnms.hxx +++ b/include/editeng/unoprnms.hxx @@ -96,6 +96,7 @@ inline constexpr OUStringLiteral UNO_NAME_SHADOWSIZEX = u"ShadowSizeX"; inline constexpr OUStringLiteral UNO_NAME_SHADOWSIZEY = u"ShadowSizeY"; inline constexpr OUStringLiteral UNO_NAME_SHADOWTRANSPARENCE = u"ShadowTransparence"; inline constexpr OUStringLiteral UNO_NAME_SHADOWBLUR = u"ShadowBlur"; +inline constexpr OUStringLiteral UNO_NAME_SHADOWALIGNMENT = u"ShadowAlignment"; inline constexpr OUStringLiteral UNO_NAME_EDGERADIUS = u"CornerRadius"; diff --git a/include/svx/RectangleAlignmentItem.hxx b/include/svx/RectangleAlignmentItem.hxx new file mode 100644 index 000000000000..91179e628a40 --- /dev/null +++ b/include/svx/RectangleAlignmentItem.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include + +namespace model +{ +enum class RectangleAlignment; +} + +/** Item that holds a rectangle alignment value. + + e.g. Top Left, Top, Top Right, Center. + @see model::RectangleAlignment + */ +class SVXCORE_DLLPUBLIC SvxRectangleAlignmentItem final + : public SfxEnumItem +{ +public: + SvxRectangleAlignmentItem(sal_uInt16 nWhich, model::RectangleAlignment nValue); + virtual ~SvxRectangleAlignmentItem() override; + + SvxRectangleAlignmentItem(SvxRectangleAlignmentItem const&) = default; + SvxRectangleAlignmentItem(SvxRectangleAlignmentItem&&) = default; + SvxRectangleAlignmentItem& operator=(SvxRectangleAlignmentItem const&) = delete; + SvxRectangleAlignmentItem& operator=(SvxRectangleAlignmentItem&&) = delete; + + virtual SvxRectangleAlignmentItem* Clone(SfxItemPool* pPool = nullptr) const override; + + virtual sal_uInt16 GetValueCount() const override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/svx/svddef.hxx b/include/svx/svddef.hxx index 84db8c4d0aa4..18088731bca1 100644 --- a/include/svx/svddef.hxx +++ b/include/svx/svddef.hxx @@ -160,6 +160,7 @@ class SvxBoxInfoItem; class SvxBoxItem; class SvxColorItem; class SvxLineItem; +class SvxRectangleAlignmentItem; class SvxTextRotateItem; class SvxWritingModeItem; class XColorItem; @@ -191,7 +192,8 @@ constexpr TypedWhichId SDRATTR_SHADOWPERSP (SDRATTR_SHADO constexpr TypedWhichId SDRATTR_SHADOWSIZEX (SDRATTR_SHADOW_FIRST+ 7); constexpr TypedWhichId SDRATTR_SHADOWSIZEY (SDRATTR_SHADOW_FIRST+ 8); constexpr TypedWhichId SDRATTR_SHADOWBLUR (SDRATTR_SHADOW_FIRST+ 9); -constexpr sal_uInt16 SDRATTR_SHADOW_LAST (SDRATTR_SHADOWBLUR); /* 1078 */ /* 1078 */ /* 1061 */ /* Pool V1: 1039 */ +constexpr TypedWhichId SDRATTR_SHADOWALIGNMENT(SDRATTR_SHADOW_FIRST + 10); +constexpr sal_uInt16 SDRATTR_SHADOW_LAST (SDRATTR_SHADOWALIGNMENT); /* 1078 */ /* 1078 */ /* 1061 */ /* Pool V1: 1039 */ constexpr sal_uInt16 SDRATTR_CAPTION_FIRST (SDRATTR_SHADOW_LAST + 1); /* 1080 */ /* 1080 */ /* 1063 */ /* Pool V1: 1041 */ constexpr TypedWhichId SDRATTR_CAPTIONTYPE (SDRATTR_CAPTION_FIRST+ 0); /* 1080 */ /* 1080 */ /* 1063 */ diff --git a/include/svx/unoshprp.hxx b/include/svx/unoshprp.hxx index a1fa9412afc9..c385f0766358 100644 --- a/include/svx/unoshprp.hxx +++ b/include/svx/unoshprp.hxx @@ -230,7 +230,8 @@ { UNO_NAME_SHADOWYDIST, SDRATTR_SHADOWYDIST, ::cppu::UnoType::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, \ { UNO_NAME_SHADOWSIZEX, SDRATTR_SHADOWSIZEX, ::cppu::UnoType::get(), 0, 0}, \ { UNO_NAME_SHADOWSIZEY, SDRATTR_SHADOWSIZEY, ::cppu::UnoType::get(), 0, 0}, \ - { UNO_NAME_SHADOWBLUR, SDRATTR_SHADOWBLUR, ::cppu::UnoType::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, + { UNO_NAME_SHADOWBLUR, SDRATTR_SHADOWBLUR, ::cppu::UnoType::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, \ + { UNO_NAME_SHADOWALIGNMENT, SDRATTR_SHADOWALIGNMENT, /*ENUM*/::cppu::UnoType::get(), 0, 0}, #define LINE_PROPERTIES_DEFAULTS\ diff --git a/oox/source/drawingml/effectproperties.cxx b/oox/source/drawingml/effectproperties.cxx index 579f4e1ab0ac..8424e3436c1a 100644 --- a/oox/source/drawingml/effectproperties.cxx +++ b/oox/source/drawingml/effectproperties.cxx @@ -14,6 +14,7 @@ #include #include +#include #include @@ -38,6 +39,7 @@ void EffectShadowProperties::assignUsed(const EffectShadowProperties& rSourcePro assignIfUsed( moShadowSy, rSourceProps.moShadowSy ); moShadowColor.assignIfUsed( rSourceProps.moShadowColor ); assignIfUsed( moShadowBlur, rSourceProps.moShadowBlur ); + assignIfUsed( moShadowAlignment, rSourceProps.moShadowAlignment ); } @@ -105,6 +107,9 @@ void EffectProperties::pushToPropMap( PropertyMap& rPropMap, rPropMap.setProperty( PROP_ShadowColor, it->moColor.getColor(rGraphicHelper ) ); rPropMap.setProperty( PROP_ShadowTransparence, it->moColor.getTransparency()); rPropMap.setProperty( PROP_ShadowBlur, convertEmuToHmm(nAttrBlur)); + rPropMap.setProperty( + PROP_ShadowAlignment, + static_cast(maShadow.moShadowAlignment.value_or(model::RectangleAlignment::Bottom))); } } diff --git a/oox/source/drawingml/effectproperties.hxx b/oox/source/drawingml/effectproperties.hxx index 54c7068ef5c6..992e2bddf3ef 100644 --- a/oox/source/drawingml/effectproperties.hxx +++ b/oox/source/drawingml/effectproperties.hxx @@ -17,6 +17,10 @@ #include #include +namespace model { +enum class RectangleAlignment; +} + namespace oox::drawingml { struct EffectGlowProperties @@ -43,6 +47,7 @@ struct EffectShadowProperties std::optional< sal_Int64 > moShadowSy; Color moShadowColor; std::optional< sal_Int64 > moShadowBlur; // size of blur effect + std::optional< model::RectangleAlignment > moShadowAlignment; /** Overwrites all members that are explicitly set in rSourceProps. */ void assignUsed( const EffectShadowProperties& rSourceProps ); diff --git a/oox/source/drawingml/effectpropertiescontext.cxx b/oox/source/drawingml/effectpropertiescontext.cxx index c8c5096829ff..017d45e4d5ee 100644 --- a/oox/source/drawingml/effectpropertiescontext.cxx +++ b/oox/source/drawingml/effectpropertiescontext.cxx @@ -87,6 +87,7 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( sal_Int32 nElement, mrEffectProperties.maShadow.moShadowSx = rAttribs.getInteger( XML_sx, 0 ); mrEffectProperties.maShadow.moShadowSy = rAttribs.getInteger( XML_sy, 0 ); mrEffectProperties.maShadow.moShadowBlur = rAttribs.getInteger( XML_blurRad, 0 ); + mrEffectProperties.maShadow.moShadowAlignment = convertToRectangleAlignment( rAttribs.getToken(XML_algn, XML_b) ); model::ColorDefinition* pColor = nullptr; if (mpEffectStyle) diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index fd2c3a0c6497..0b6e5437b883 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -471,6 +471,7 @@ Segments SelectedItems SelectedPage Shadow +ShadowAlignment ShadowColor ShadowFormat ShadowSizeX diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk index 9ecc9ec58fc4..5a7e48a47018 100644 --- a/svx/Library_svxcore.mk +++ b/svx/Library_svxcore.mk @@ -219,6 +219,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\ svx/source/items/customshapeitem \ svx/source/items/drawitem \ svx/source/items/e3ditem \ + svx/source/items/RectangleAlignmentItem \ svx/source/items/galleryitem \ svx/source/items/grfitem \ svx/source/sdr/animation/scheduler \ diff --git a/svx/qa/unit/data/tdf150020-shadow-alignment.pptx b/svx/qa/unit/data/tdf150020-shadow-alignment.pptx new file mode 100644 index 0000000000000000000000000000000000000000..caba1a122da53f4721d75e1f5b03af730bd1950f GIT binary patch literal 51529 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 literal 0 HcmV?d00001 diff --git a/svx/qa/unit/sdr.cxx b/svx/qa/unit/sdr.cxx index 432eeeaa4999..b98df8b58041 100644 --- a/svx/qa/unit/sdr.cxx +++ b/svx/qa/unit/sdr.cxx @@ -80,6 +80,53 @@ CPPUNIT_TEST_FIXTURE(SdrTest, testShadowScaleOrigin) CPPUNIT_ASSERT_EQUAL(sal_Int32(-684), fShadowY); } +CPPUNIT_TEST_FIXTURE(SdrTest, testShadowAlignment) +{ + loadFromURL(u"tdf150020-shadow-alignment.pptx"); + + uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), + uno::UNO_QUERY); + drawinglayer::primitive2d::Primitive2DContainer xPrimitiveSequence + = renderPageToPrimitives(xDrawPage); + + // Examine the created primitives. + drawinglayer::Primitive2dXmlDump aDumper; + xmlDocUniquePtr pDocument = aDumper.dumpAndParse(xPrimitiveSequence); + + // Without the accompanying fix in place, this test would have failed with: + // - Expected: -567 + // - Actual : 162 + // - In <>, attribute 'xy13' of '(//shadow/transform)[1]' incorrect value. + // i.e. shadow alignment was ignored while scaling the shadow. + assertXPath(pDocument, "(//shadow/transform)[1]", "xy13", "-567"); + assertXPath(pDocument, "(//shadow/transform)[1]", "xy23", "162"); + + assertXPath(pDocument, "(//shadow/transform)[2]", "xy13", "-1794"); + assertXPath(pDocument, "(//shadow/transform)[2]", "xy23", "162"); + + assertXPath(pDocument, "(//shadow/transform)[3]", "xy13", "-3021"); + assertXPath(pDocument, "(//shadow/transform)[3]", "xy23", "161"); + + assertXPath(pDocument, "(//shadow/transform)[4]", "xy13", "-567"); + assertXPath(pDocument, "(//shadow/transform)[4]", "xy23", "-749"); + + assertXPath(pDocument, "(//shadow/transform)[5]", "xy13", "-3021"); + assertXPath(pDocument, "(//shadow/transform)[5]", "xy23", "-750"); + + assertXPath(pDocument, "(//shadow/transform)[6]", "xy13", "-566"); + assertXPath(pDocument, "(//shadow/transform)[6]", "xy23", "-1691"); + + assertXPath(pDocument, "(//shadow/transform)[7]", "xy13", "-1794"); + assertXPath(pDocument, "(//shadow/transform)[7]", "xy23", "-1693"); + + assertXPath(pDocument, "(//shadow/transform)[8]", "xy13", "-3022"); + assertXPath(pDocument, "(//shadow/transform)[8]", "xy23", "-1691"); + + assertXPath(pDocument, "(//shadow/transform)[9]", "xy13", "-1794"); + assertXPath(pDocument, "(//shadow/transform)[9]", "xy23", "-750"); +} + CPPUNIT_TEST_FIXTURE(SdrTest, testZeroWidthTextWrap) { // Load a document containing a 0-width shape with text. diff --git a/svx/source/items/RectangleAlignmentItem.cxx b/svx/source/items/RectangleAlignmentItem.cxx new file mode 100644 index 000000000000..3b0b7b0f1081 --- /dev/null +++ b/svx/source/items/RectangleAlignmentItem.cxx @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include + +SvxRectangleAlignmentItem::SvxRectangleAlignmentItem(sal_uInt16 nWhich, + model::RectangleAlignment nValue) + : SfxEnumItem(nWhich, nValue) +{ +} + +SvxRectangleAlignmentItem::~SvxRectangleAlignmentItem() {} + +SvxRectangleAlignmentItem* SvxRectangleAlignmentItem::Clone(SfxItemPool*) const +{ + return new SvxRectangleAlignmentItem(*this); +} + +sal_uInt16 SvxRectangleAlignmentItem::GetValueCount() const +{ + return model::RECTANGLE_ALIGNMENT_COUNT; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx index e1f6fc10c45a..963bba567f6d 100644 --- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx +++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -402,7 +403,9 @@ namespace drawinglayer::primitive2d sal_Int32 nBlur(rSet.Get(SDRATTR_SHADOWBLUR).GetValue()); - return attribute::SdrShadowAttribute(aOffset, aSize, static_cast(nTransparence) * 0.01,nBlur, aColor.getBColor()); + model::RectangleAlignment eAlignment{rSet.Get(SDRATTR_SHADOWALIGNMENT).GetValue()}; + + return attribute::SdrShadowAttribute(aOffset, aSize, static_cast(nTransparence) * 0.01, nBlur, eAlignment, aColor.getBColor()); } } diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx index 1a5459643006..b5df830d73fe 100644 --- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx @@ -49,6 +49,7 @@ #include #include #include +#include #include // for SlideBackgroundFillPrimitive2D @@ -65,6 +66,35 @@ namespace drawinglayer::primitive2d { namespace { +/// @returns the offset to apply/unapply to scale according to correct origin for a given alignment. +basegfx::B2DTuple getShadowScaleOriginOffset(const basegfx::B2DTuple& aScale, + model::RectangleAlignment eAlignment) +{ + switch (eAlignment) + { + case model::RectangleAlignment::TopLeft: + return { 0, 0 }; + case model::RectangleAlignment::Top: + return { aScale.getX() / 2, 0 }; + case model::RectangleAlignment::TopRight: + return { aScale.getX(), 0 }; + case model::RectangleAlignment::Left: + return { 0, aScale.getY() / 2 }; + case model::RectangleAlignment::Center: + return { aScale.getX() / 2, aScale.getY() / 2 }; + case model::RectangleAlignment::Right: + return { aScale.getX(), aScale.getY() / 2 }; + case model::RectangleAlignment::BottomLeft: + return { 0, aScale.getY() }; + case model::RectangleAlignment::Bottom: + return { aScale.getX() / 2, aScale.getY() }; + case model::RectangleAlignment::BottomRight: + return { aScale.getX(), aScale.getY() }; + default: + return { 0, 0 }; + } +}; + // See also: SdrTextObj::AdjustRectToTextDistance basegfx::B2DRange getTextAnchorRange(const attribute::SdrTextAttribute& rText, const basegfx::B2DRange& rSnapRange) @@ -775,19 +805,10 @@ sal_uInt32 SlideBackgroundFillPrimitive2D::getPrimitive2DID() const double fShearX = 0; rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); // Scale the shadow - double nTranslateX = aTranslate.getX(); - double nTranslateY = aTranslate.getY(); - - // The origin for scaling is the top left corner by default. A negative - // shadow offset changes the origin. - if (rShadow.getOffset().getX() < 0) - nTranslateX += aScale.getX(); - if (rShadow.getOffset().getY() < 0) - nTranslateY += aScale.getY(); - - aShadowOffset.translate(-nTranslateX, -nTranslateY); + aTranslate += getShadowScaleOriginOffset(aScale, rShadow.getAlignment()); + aShadowOffset.translate(-aTranslate); aShadowOffset.scale(rShadow.getSize().getX() * 0.00001, rShadow.getSize().getY() * 0.00001); - aShadowOffset.translate(nTranslateX, nTranslateY); + aShadowOffset.translate(aTranslate); } aShadowOffset.translate(rShadow.getOffset().getX(), rShadow.getOffset().getY()); diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx index 1898f13140ae..4cc184246159 100644 --- a/svx/source/svdraw/svdattr.cxx +++ b/svx/source/svdraw/svdattr.cxx @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -95,6 +97,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +138,7 @@ SdrItemPool::SdrItemPool( rPoolDefaults[SDRATTR_SHADOWSIZEY -SDRATTR_START]=new SdrMetricItem(SDRATTR_SHADOWSIZEY, 100000); rPoolDefaults[SDRATTR_SHADOWTRANSPARENCE-SDRATTR_START]=new SdrPercentItem(SDRATTR_SHADOWTRANSPARENCE, 0); rPoolDefaults[SDRATTR_SHADOWBLUR -SDRATTR_START]=new SdrMetricItem(SDRATTR_SHADOWBLUR, 0); + rPoolDefaults[SDRATTR_SHADOWALIGNMENT -SDRATTR_START]=new SvxRectangleAlignmentItem(SDRATTR_SHADOWALIGNMENT, model::RectangleAlignment::Unset); rPoolDefaults[SDRATTR_SHADOW3D -SDRATTR_START]=new SfxVoidItem(SDRATTR_SHADOW3D ); rPoolDefaults[SDRATTR_SHADOWPERSP -SDRATTR_START]=new SfxVoidItem(SDRATTR_SHADOWPERSP ); rPoolDefaults[SDRATTR_CAPTIONTYPE -SDRATTR_START]=new SdrCaptionTypeItem ; diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 518916df3785..ab10a2af2bf0 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -1157,22 +1158,30 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf137025) // SDRATTR_TEXT_LEFTDIST assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObject" - "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item[@whichId='1072']", + "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item" + "[@whichId='" + + OString::number(SDRATTR_TEXT_LEFTDIST) + "']", "value", "567"); // SDRATTR_TEXT_RIGHTDIST assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObject" - "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item[@whichId='1073']", + "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item" + "[@whichId='" + + OString::number(SDRATTR_TEXT_RIGHTDIST) + "']", "value", "1134"); // SDRATTR_TEXT_UPPERDIST assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObject" - "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item[@whichId='1074']", + "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item" + "[@whichId='" + + OString::number(SDRATTR_TEXT_UPPERDIST) + "']", "value", "1701"); // SDRATTR_TEXT_LOWERDIST assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObject" - "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item[@whichId='1075']", + "/DefaultProperties/SfxItemSet/SdrMetricItem/SfxInt32Item" + "[@whichId='" + + OString::number(SDRATTR_TEXT_LOWERDIST) + "']", "value", "2268"); // Check the textbox-shape import too